<!DOCTYPE html><html lang="zh-CN" data-theme="light"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><title>设计模式 | Zhang Shuo'blog</title><meta name="keywords" content="设计模式"><meta name="author" content="Zhang Shuo"><meta name="copyright" content="Zhang Shuo"><meta name="format-detection" content="telephone=no"><meta name="theme-color" content="#ffffff"><meta name="description" content="title: 设计模式date: 2021-12-6 17:36:00tags: 设计模式categories: 设计模式    一、概述 二、创建型 1. 单例（Singleton） Intent Class Diagram Implementation Examples JDK   2. 简单工厂（Simple Factory） Intent Class Diagram Implementat">
<meta property="og:type" content="article">
<meta property="og:title" content="设计模式">
<meta property="og:url" content="https://zhang-shuo-fr.gitee.io/hexo3/2021/12/06/notes/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/index.html">
<meta property="og:site_name" content="Zhang Shuo&#39;blog">
<meta property="og:description" content="title: 设计模式date: 2021-12-6 17:36:00tags: 设计模式categories: 设计模式    一、概述 二、创建型 1. 单例（Singleton） Intent Class Diagram Implementation Examples JDK   2. 简单工厂（Simple Factory） Intent Class Diagram Implementat">
<meta property="og:locale" content="zh_CN">
<meta property="og:image" content="https://zhang-shuo-fr.gitee.io/hexo3/img/20.jpg">
<meta property="article:published_time" content="2021-12-06T09:36:00.000Z">
<meta property="article:modified_time" content="2021-12-10T13:16:36.209Z">
<meta property="article:author" content="Zhang Shuo">
<meta property="article:tag" content="设计模式">
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="https://zhang-shuo-fr.gitee.io/hexo3/img/20.jpg"><link rel="shortcut icon" href="/hexo3/img/mao_tou_xiang.jpg"><link rel="canonical" href="https://zhang-shuo-fr.gitee.io/hexo3/2021/12/06/notes/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/"><link rel="preconnect" href="//cdn.jsdelivr.net"/><link rel="preconnect" href="//fonts.googleapis.com" crossorigin=""/><link rel="preconnect" href="//busuanzi.ibruce.info"/><link rel="manifest" href="/hexo3/pwa/manifest.json"/><link rel="apple-touch-icon" sizes="180x180" href="/hexo3/pwa/apple-touch-icon.png"/><link rel="icon" type="image/png" sizes="32x32" href="/hexo3/pwa/32.png"/><link rel="icon" type="image/png" sizes="16x16" href="/hexo3/pwa/16.png"/><link rel="mask-icon" href="/hexo3/pwa/safari-pinned-tab.svg" color="#5bbad5"/><link rel="stylesheet" href="/hexo3/css/index.css"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free/css/all.min.css" media="print" onload="this.media='all'"><link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Titillium+Web&amp;display=swap" media="print" onload="this.media='all'"><script>const GLOBAL_CONFIG = { 
  root: '/hexo3/',
  algolia: undefined,
  localSearch: {"path":"search.xml","languages":{"hits_empty":"找不到您查询的内容：${query}"}},
  translate: {"defaultEncoding":2,"translateDelay":0,"msgToTraditionalChinese":"繁","msgToSimplifiedChinese":"簡"},
  noticeOutdate: undefined,
  highlight: {"plugin":"highlighjs","highlightCopy":true,"highlightLang":true,"highlightHeightLimit":false},
  copy: {
    success: '复制成功',
    error: '复制错误',
    noSupport: '浏览器不支持'
  },
  relativeDate: {
    homepage: true,
    post: true
  },
  runtime: '天',
  date_suffix: {
    just: '刚刚',
    min: '分钟前',
    hour: '小时前',
    day: '天前',
    month: '个月前'
  },
  copyright: undefined,
  lightbox: 'fancybox',
  Snackbar: undefined,
  source: {
    jQuery: 'https://cdn.jsdelivr.net/npm/jquery@latest/dist/jquery.min.js',
    justifiedGallery: {
      js: 'https://cdn.jsdelivr.net/npm/justifiedGallery/dist/js/jquery.justifiedGallery.min.js',
      css: 'https://cdn.jsdelivr.net/npm/justifiedGallery/dist/css/justifiedGallery.min.css'
    },
    fancybox: {
      js: 'https://cdn.jsdelivr.net/npm/@fancyapps/fancybox@latest/dist/jquery.fancybox.min.js',
      css: 'https://cdn.jsdelivr.net/npm/@fancyapps/fancybox@latest/dist/jquery.fancybox.min.css'
    }
  },
  isPhotoFigcaption: false,
  islazyload: true,
  isanchor: true
}</script><script id="config-diff">var GLOBAL_CONFIG_SITE = {
  title: '设计模式',
  isPost: true,
  isHome: false,
  isHighlightShrink: undefined,
  isToc: true,
  postUpdate: '2021-12-10 21:16:36'
}</script><noscript><style type="text/css">
  #nav {
    opacity: 1
  }
  .justified-gallery img {
    opacity: 1
  }

  #recent-posts time,
  #post-meta time {
    display: inline !important
  }
</style></noscript><script>(win=>{
    win.saveToLocal = {
      set: function setWithExpiry(key, value, ttl) {
        if (ttl === 0) return
        const now = new Date()
        const expiryDay = ttl * 86400000
        const item = {
          value: value,
          expiry: now.getTime() + expiryDay,
        }
        localStorage.setItem(key, JSON.stringify(item))
      },

      get: function getWithExpiry(key) {
        const itemStr = localStorage.getItem(key)

        if (!itemStr) {
          return undefined
        }
        const item = JSON.parse(itemStr)
        const now = new Date()

        if (now.getTime() > item.expiry) {
          localStorage.removeItem(key)
          return undefined
        }
        return item.value
      }
    }
  
    win.getScript = url => new Promise((resolve, reject) => {
      const script = document.createElement('script')
      script.src = url
      script.async = true
      script.onerror = reject
      script.onload = script.onreadystatechange = function() {
        const loadState = this.readyState
        if (loadState && loadState !== 'loaded' && loadState !== 'complete') return
        script.onload = script.onreadystatechange = null
        resolve()
      }
      document.head.appendChild(script)
    })
  
      win.activateDarkMode = function () {
        document.documentElement.setAttribute('data-theme', 'dark')
        if (document.querySelector('meta[name="theme-color"]') !== null) {
          document.querySelector('meta[name="theme-color"]').setAttribute('content', '#0d0d0d')
        }
      }
      win.activateLightMode = function () {
        document.documentElement.setAttribute('data-theme', 'light')
        if (document.querySelector('meta[name="theme-color"]') !== null) {
          document.querySelector('meta[name="theme-color"]').setAttribute('content', '#ffffff')
        }
      }
      const t = saveToLocal.get('theme')
    
          if (t === 'dark') activateDarkMode()
          else if (t === 'light') activateLightMode()
        
      const asideStatus = saveToLocal.get('aside-status')
      if (asideStatus !== undefined) {
        if (asideStatus === 'hide') {
          document.documentElement.classList.add('hide-aside')
        } else {
          document.documentElement.classList.remove('hide-aside')
        }
      }
    
    const fontSizeVal = saveToLocal.get('global-font-size')
    if (fontSizeVal !== undefined) {
      document.documentElement.style.setProperty('--global-font-size', fontSizeVal + 'px')
    }
    
    const detectApple = () => {
      if (GLOBAL_CONFIG_SITE.isHome && /iPad|iPhone|iPod|Macintosh/.test(navigator.userAgent)){
        document.documentElement.classList.add('apple')
      }
    }
    detectApple()
    document.addEventListener('pjax:complete', detectApple)})(window)</script><style type="text/css">#toggle-sidebar {left:100px}</style><meta name="generator" content="Hexo 5.4.0"></head><body><div id="loading-box"><div class="loading-left-bg"></div><div class="loading-right-bg"></div><div class="spinner-box"><div class="configure-border-1"><div class="configure-core"></div></div><div class="configure-border-2"><div class="configure-core"></div></div><div class="loading-word">加载中...</div></div></div><div id="web_bg"></div><div id="sidebar"><div id="menu-mask"></div><div id="sidebar-menus"><div class="avatar-img is-center"><img src= "" data-lazy-src="/hexo3/img/mao_tou_xiang.jpg" onerror="onerror=null;src='/img/friend_404.gif'" alt="avatar"/></div><div class="site-data"><div class="data-item is-center"><div class="data-item-link"><a href="/hexo3/archives/"><div class="headline">文章</div><div class="length-num">176</div></a></div></div><div class="data-item is-center"><div class="data-item-link"><a href="/hexo3/tags/"><div class="headline">标签</div><div class="length-num">45</div></a></div></div><div class="data-item is-center"><div class="data-item-link"><a href="/hexo3/categories/"><div class="headline">分类</div><div class="length-num">15</div></a></div></div></div><hr/><div class="menus_items"><div class="menus_item"><a class="site-page" href="/hexo3/"><i class="fa-fw fas fa-home"></i><span> 首页</span></a></div><div class="menus_item"><a class="site-page" href="/hexo3/archives/"><i class="fa-fw fas fa-archive"></i><span> 时间轴</span></a></div><div class="menus_item"><a class="site-page" href="/hexo3/tags/"><i class="fa-fw fas fa-tags"></i><span> 标签</span></a></div><div class="menus_item"><a class="site-page" href="/hexo3/categories/"><i class="fa-fw fas fa-folder-open"></i><span> 分类</span></a></div><div class="menus_item"><a class="site-page" href="javascript:void(0);"><i class="fa-fw fa fa-heartbeat"></i><span> 小窝</span><i class="fas fa-chevron-down expand"></i></a><ul class="menus_item_child"><li><a class="site-page child" href="/hexo3/music/"><i class="fa-fw fas fa-music"></i><span> 音乐</span></a></li><li><a class="site-page child" href="/hexo3/Gallery/"><i class="fa-fw fas fa-images"></i><span> 照片</span></a></li><li><a class="site-page child" href="/hexo3/movies/"><i class="fa-fw fas fa-video"></i><span> 电影</span></a></li></ul></div><div class="menus_item"><a class="site-page" href="/hexo3/link/"><i class="fa-fw fas fa-link"></i><span> 友链</span></a></div><div class="menus_item"><a class="site-page" href="/hexo3/about/"><i class="fa-fw fas fa-heart"></i><span> 关于</span></a></div></div></div></div><div class="post" id="body-wrap"><header class="post-bg" id="page-header" style="background-image: url('/hexo3/img/20.jpg')"><nav id="nav"><span id="blog_name"><a id="site-name" href="/hexo3/">Zhang Shuo'blog</a></span><div id="menus"><div id="search-button"><a class="site-page social-icon search"><i class="fas fa-search fa-fw"></i><span> 搜索</span></a></div><div class="menus_items"><div class="menus_item"><a class="site-page" href="/hexo3/"><i class="fa-fw fas fa-home"></i><span> 首页</span></a></div><div class="menus_item"><a class="site-page" href="/hexo3/archives/"><i class="fa-fw fas fa-archive"></i><span> 时间轴</span></a></div><div class="menus_item"><a class="site-page" href="/hexo3/tags/"><i class="fa-fw fas fa-tags"></i><span> 标签</span></a></div><div class="menus_item"><a class="site-page" href="/hexo3/categories/"><i class="fa-fw fas fa-folder-open"></i><span> 分类</span></a></div><div class="menus_item"><a class="site-page" href="javascript:void(0);"><i class="fa-fw fa fa-heartbeat"></i><span> 小窝</span><i class="fas fa-chevron-down expand"></i></a><ul class="menus_item_child"><li><a class="site-page child" href="/hexo3/music/"><i class="fa-fw fas fa-music"></i><span> 音乐</span></a></li><li><a class="site-page child" href="/hexo3/Gallery/"><i class="fa-fw fas fa-images"></i><span> 照片</span></a></li><li><a class="site-page child" href="/hexo3/movies/"><i class="fa-fw fas fa-video"></i><span> 电影</span></a></li></ul></div><div class="menus_item"><a class="site-page" href="/hexo3/link/"><i class="fa-fw fas fa-link"></i><span> 友链</span></a></div><div class="menus_item"><a class="site-page" href="/hexo3/about/"><i class="fa-fw fas fa-heart"></i><span> 关于</span></a></div></div><div id="toggle-menu"><a class="site-page"><i class="fas fa-bars fa-fw"></i></a></div></div></nav><div id="post-info"><h1 class="post-title">设计模式</h1><div id="post-meta"><div class="meta-firstline"><span class="post-meta-date"><i class="far fa-calendar-alt fa-fw post-meta-icon"></i><span class="post-meta-label">发表于</span><time class="post-meta-date-created" datetime="2021-12-06T09:36:00.000Z" title="发表于 2021-12-06 17:36:00">2021-12-06</time><span class="post-meta-separator">|</span><i class="fas fa-history fa-fw post-meta-icon"></i><span class="post-meta-label">更新于</span><time class="post-meta-date-updated" datetime="2021-12-10T13:16:36.209Z" title="更新于 2021-12-10 21:16:36">2021-12-10</time></span><span class="post-meta-categories"><span class="post-meta-separator">|</span><i class="fas fa-inbox fa-fw post-meta-icon"></i><a class="post-meta-categories" href="/hexo3/categories/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/">设计模式</a></span></div><div class="meta-secondline"><span class="post-meta-separator">|</span><span class="post-meta-wordcount"><i class="far fa-file-word fa-fw post-meta-icon"></i><span class="post-meta-label">字数总计:</span><span class="word-count">11.2k</span><span class="post-meta-separator">|</span><i class="far fa-clock fa-fw post-meta-icon"></i><span class="post-meta-label">阅读时长:</span><span>52分钟</span></span><span class="post-meta-separator">|</span><span class="post-meta-pv-cv" id="" data-flag-title="设计模式"><i class="far fa-eye fa-fw post-meta-icon"></i><span class="post-meta-label">阅读量:</span><span id="busuanzi_value_page_pv"></span></span></div></div></div></header><main class="layout" id="content-inner"><div id="post"><article class="post-content" id="article-container"><p>title: 设计模式<br>date: 2021-12-6 17:36:00<br>tags: 设计模式<br>categories: 设计模式</p>
<hr>
<!-- GFM-TOC -->
<ul>
<li><a href="#%E4%B8%80%E6%A6%82%E8%BF%B0">一、概述</a></li>
<li><a href="#%E4%BA%8C%E5%88%9B%E5%BB%BA%E5%9E%8B">二、创建型</a><ul>
<li><a href="#1-%E5%8D%95%E4%BE%8Bsingleton">1. 单例（Singleton）</a><ul>
<li><a href="#intent">Intent</a></li>
<li><a href="#class-diagram">Class Diagram</a></li>
<li><a href="#implementation">Implementation</a></li>
<li><a href="#examples">Examples</a></li>
<li><a href="#jdk">JDK</a></li>
</ul>
</li>
<li><a href="#2-%E7%AE%80%E5%8D%95%E5%B7%A5%E5%8E%82simple-factory">2. 简单工厂（Simple Factory）</a><ul>
<li><a href="#intent">Intent</a></li>
<li><a href="#class-diagram">Class Diagram</a></li>
<li><a href="#implementation">Implementation</a></li>
</ul>
</li>
<li><a href="#3-%E5%B7%A5%E5%8E%82%E6%96%B9%E6%B3%95factory-method">3. 工厂方法（Factory Method）</a><ul>
<li><a href="#intent">Intent</a></li>
<li><a href="#class-diagram">Class Diagram</a></li>
<li><a href="#implementation">Implementation</a></li>
<li><a href="#jdk">JDK</a></li>
</ul>
</li>
<li><a href="#4-%E6%8A%BD%E8%B1%A1%E5%B7%A5%E5%8E%82abstract-factory">4. 抽象工厂（Abstract Factory）</a><ul>
<li><a href="#intent">Intent</a></li>
<li><a href="#class-diagram">Class Diagram</a></li>
<li><a href="#implementation">Implementation</a></li>
<li><a href="#jdk">JDK</a></li>
</ul>
</li>
<li><a href="#5-%E7%94%9F%E6%88%90%E5%99%A8builder">5. 生成器（Builder）</a><ul>
<li><a href="#intent">Intent</a></li>
<li><a href="#class-diagram">Class Diagram</a></li>
<li><a href="#implementation">Implementation</a></li>
<li><a href="#jdk">JDK</a></li>
</ul>
</li>
<li><a href="#6-%E5%8E%9F%E5%9E%8B%E6%A8%A1%E5%BC%8Fprototype">6. 原型模式（Prototype）</a><ul>
<li><a href="#intent">Intent</a></li>
<li><a href="#class-diagram">Class Diagram</a></li>
<li><a href="#implementation">Implementation</a></li>
<li><a href="#jdk">JDK</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#%E4%B8%89%E8%A1%8C%E4%B8%BA%E5%9E%8B">三、行为型</a><ul>
<li><a href="#1-%E8%B4%A3%E4%BB%BB%E9%93%BEchain-of-responsibility">1. 责任链（Chain Of Responsibility）</a><ul>
<li><a href="#intent">Intent</a></li>
<li><a href="#class-diagram">Class Diagram</a></li>
<li><a href="#implementation">Implementation</a></li>
<li><a href="#jdk">JDK</a></li>
</ul>
</li>
<li><a href="#2-%E5%91%BD%E4%BB%A4command">2. 命令（Command）</a><ul>
<li><a href="#intent">Intent</a></li>
<li><a href="#class-diagram">Class Diagram</a></li>
<li><a href="#implementation">Implementation</a></li>
<li><a href="#jdk">JDK</a></li>
</ul>
</li>
<li><a href="#3-%E8%A7%A3%E9%87%8A%E5%99%A8interpreter">3. 解释器（Interpreter）</a><ul>
<li><a href="#intent">Intent</a></li>
<li><a href="#class-diagram">Class Diagram</a></li>
<li><a href="#implementation">Implementation</a></li>
<li><a href="#jdk">JDK</a></li>
</ul>
</li>
<li><a href="#4-%E8%BF%AD%E4%BB%A3%E5%99%A8iterator">4. 迭代器（Iterator）</a><ul>
<li><a href="#intent">Intent</a></li>
<li><a href="#class-diagram">Class Diagram</a></li>
<li><a href="#implementation">Implementation</a></li>
<li><a href="#jdk">JDK</a></li>
</ul>
</li>
<li><a href="#5-%E4%B8%AD%E4%BB%8B%E8%80%85mediator">5. 中介者（Mediator）</a><ul>
<li><a href="#intent">Intent</a></li>
<li><a href="#class-diagram">Class Diagram</a></li>
<li><a href="#implementation">Implementation</a></li>
<li><a href="#jdk">JDK</a></li>
</ul>
</li>
<li><a href="#6-%E5%A4%87%E5%BF%98%E5%BD%95memento">6. 备忘录（Memento）</a><ul>
<li><a href="#intent">Intent</a></li>
<li><a href="#class-diagram">Class Diagram</a></li>
<li><a href="#implementation">Implementation</a></li>
<li><a href="#jdk">JDK</a></li>
</ul>
</li>
<li><a href="#7-%E8%A7%82%E5%AF%9F%E8%80%85observer">7. 观察者（Observer）</a><ul>
<li><a href="#intent">Intent</a></li>
<li><a href="#class-diagram">Class Diagram</a></li>
<li><a href="#implementation">Implementation</a></li>
<li><a href="#jdk">JDK</a></li>
</ul>
</li>
<li><a href="#8-%E7%8A%B6%E6%80%81state">8. 状态（State）</a><ul>
<li><a href="#intent">Intent</a></li>
<li><a href="#class-diagram">Class Diagram</a></li>
<li><a href="#implementation">Implementation</a></li>
</ul>
</li>
<li><a href="#9-%E7%AD%96%E7%95%A5strategy">9. 策略（Strategy）</a><ul>
<li><a href="#intent">Intent</a></li>
<li><a href="#class-diagram">Class Diagram</a></li>
<li><a href="#%E4%B8%8E%E7%8A%B6%E6%80%81%E6%A8%A1%E5%BC%8F%E7%9A%84%E6%AF%94%E8%BE%83">与状态模式的比较</a></li>
<li><a href="#implementation">Implementation</a></li>
<li><a href="#jdk">JDK</a></li>
</ul>
</li>
<li><a href="#10-%E6%A8%A1%E6%9D%BF%E6%96%B9%E6%B3%95template-method">10. 模板方法（Template Method）</a><ul>
<li><a href="#intent">Intent</a></li>
<li><a href="#class-diagram">Class Diagram</a></li>
<li><a href="#implementation">Implementation</a></li>
<li><a href="#jdk">JDK</a></li>
</ul>
</li>
<li><a href="#11-%E8%AE%BF%E9%97%AE%E8%80%85visitor">11. 访问者（Visitor）</a><ul>
<li><a href="#intent">Intent</a></li>
<li><a href="#class-diagram">Class Diagram</a></li>
<li><a href="#implementation">Implementation</a></li>
<li><a href="#jdk">JDK</a></li>
</ul>
</li>
<li><a href="#12-%E7%A9%BA%E5%AF%B9%E8%B1%A1null">12. 空对象（Null）</a><ul>
<li><a href="#intent">Intent</a></li>
<li><a href="#class-diagram">Class Diagram</a></li>
<li><a href="#implementation">Implementation</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#%E5%9B%9B%E7%BB%93%E6%9E%84%E5%9E%8B">四、结构型</a><ul>
<li><a href="#1-%E9%80%82%E9%85%8D%E5%99%A8adapter">1. 适配器（Adapter）</a><ul>
<li><a href="#intent">Intent</a></li>
<li><a href="#class-diagram">Class Diagram</a></li>
<li><a href="#implementation">Implementation</a></li>
<li><a href="#jdk">JDK</a></li>
</ul>
</li>
<li><a href="#2-%E6%A1%A5%E6%8E%A5bridge">2. 桥接（Bridge）</a><ul>
<li><a href="#intent">Intent</a></li>
<li><a href="#class-diagram">Class Diagram</a></li>
<li><a href="#implementation">Implementation</a></li>
<li><a href="#jdk">JDK</a></li>
</ul>
</li>
<li><a href="#3-%E7%BB%84%E5%90%88composite">3. 组合（Composite）</a><ul>
<li><a href="#intent">Intent</a></li>
<li><a href="#class-diagram">Class Diagram</a></li>
<li><a href="#implementation">Implementation</a></li>
<li><a href="#jdk">JDK</a></li>
</ul>
</li>
<li><a href="#4-%E8%A3%85%E9%A5%B0decorator">4. 装饰（Decorator）</a><ul>
<li><a href="#intent">Intent</a></li>
<li><a href="#class-diagram">Class Diagram</a></li>
<li><a href="#implementation">Implementation</a></li>
<li><a href="#%E8%AE%BE%E8%AE%A1%E5%8E%9F%E5%88%99">设计原则</a></li>
<li><a href="#jdk">JDK</a></li>
</ul>
</li>
<li><a href="#5-%E5%A4%96%E8%A7%82facade">5. 外观（Facade）</a><ul>
<li><a href="#intent">Intent</a></li>
<li><a href="#class-diagram">Class Diagram</a></li>
<li><a href="#implementation">Implementation</a></li>
<li><a href="#%E8%AE%BE%E8%AE%A1%E5%8E%9F%E5%88%99">设计原则</a></li>
</ul>
</li>
<li><a href="#6-%E4%BA%AB%E5%85%83flyweight">6. 享元（Flyweight）</a><ul>
<li><a href="#intent">Intent</a></li>
<li><a href="#class-diagram">Class Diagram</a></li>
<li><a href="#implementation">Implementation</a></li>
<li><a href="#jdk">JDK</a></li>
</ul>
</li>
<li><a href="#7-%E4%BB%A3%E7%90%86proxy">7. 代理（Proxy）</a><ul>
<li><a href="#intent">Intent</a></li>
<li><a href="#class-diagram">Class Diagram</a></li>
<li><a href="#implementation">Implementation</a></li>
<li><a href="#jdk">JDK</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#%E5%8F%82%E8%80%83%E8%B5%84%E6%96%99">参考资料</a><!-- GFM-TOC --></li>
</ul>
<h1 id="一、概述"><a href="#一、概述" class="headerlink" title="一、概述"></a>一、概述</h1><p>设计模式是解决问题的方案，学习现有的设计模式可以做到经验复用。</p>
<p>拥有设计模式词汇，在沟通时就能用更少的词汇来讨论，并且不需要了解底层细节。</p>
<h1 id="二、创建型"><a href="#二、创建型" class="headerlink" title="二、创建型"></a>二、创建型</h1><h2 id="1-单例（Singleton）"><a href="#1-单例（Singleton）" class="headerlink" title="1. 单例（Singleton）"></a>1. 单例（Singleton）</h2><h3 id="Intent"><a href="#Intent" class="headerlink" title="Intent"></a>Intent</h3><p>确保一个类只有一个实例，并提供该实例的全局访问点。</p>
<h3 id="Class-Diagram"><a href="#Class-Diagram" class="headerlink" title="Class Diagram"></a>Class Diagram</h3><p>使用一个私有构造函数、一个私有静态变量以及一个公有静态函数来实现。</p>
<p>私有构造函数保证了不能通过构造函数来创建对象实例，只能通过公有静态函数返回唯一的私有静态变量。</p>
<div align="center"> <img src= "" data-lazy-src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/eca1f422-8381-409b-ad04-98ef39ae38ba.png"/> </div><br>

<h3 id="Implementation"><a href="#Implementation" class="headerlink" title="Implementation"></a>Implementation</h3><h4 id="Ⅰ-懒汉式-线程不安全"><a href="#Ⅰ-懒汉式-线程不安全" class="headerlink" title="Ⅰ 懒汉式-线程不安全"></a>Ⅰ 懒汉式-线程不安全</h4><p>以下实现中，私有静态变量 uniqueInstance 被延迟实例化，这样做的好处是，如果没有用到该类，那么就不会实例化 uniqueInstance，从而节约资源。</p>
<p>这个实现在多线程环境下是不安全的，如果多个线程能够同时进入 <code>if (uniqueInstance == null)</code> ，并且此时 uniqueInstance 为 null，那么会有多个线程执行 <code>uniqueInstance = new Singleton();</code> 语句，这将导致实例化多次 uniqueInstance。</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Singleton</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">static</span> Singleton uniqueInstance;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">private</span> <span class="title">Singleton</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> Singleton <span class="title">getUniqueInstance</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">if</span> (uniqueInstance == <span class="keyword">null</span>) &#123;</span><br><span class="line">            uniqueInstance = <span class="keyword">new</span> Singleton();</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> uniqueInstance;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h4 id="Ⅱ-饿汉式-线程安全"><a href="#Ⅱ-饿汉式-线程安全" class="headerlink" title="Ⅱ 饿汉式-线程安全"></a>Ⅱ 饿汉式-线程安全</h4><p>线程不安全问题主要是由于 uniqueInstance 被实例化多次，采取直接实例化 uniqueInstance 的方式就不会产生线程不安全问题。</p>
<p>但是直接实例化的方式也丢失了延迟实例化带来的节约资源的好处。</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">private</span> <span class="keyword">static</span> Singleton uniqueInstance = <span class="keyword">new</span> Singleton();</span><br></pre></td></tr></table></figure>

<h4 id="Ⅲ-懒汉式-线程安全"><a href="#Ⅲ-懒汉式-线程安全" class="headerlink" title="Ⅲ 懒汉式-线程安全"></a>Ⅲ 懒汉式-线程安全</h4><p>只需要对 getUniqueInstance() 方法加锁，那么在一个时间点只能有一个线程能够进入该方法，从而避免了实例化多次 uniqueInstance。</p>
<p>但是当一个线程进入该方法之后，其它试图进入该方法的线程都必须等待，即使 uniqueInstance 已经被实例化了。这会让线程阻塞时间过长，因此该方法有性能问题，不推荐使用。</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">synchronized</span> Singleton <span class="title">getUniqueInstance</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (uniqueInstance == <span class="keyword">null</span>) &#123;</span><br><span class="line">        uniqueInstance = <span class="keyword">new</span> Singleton();</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> uniqueInstance;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h4 id="Ⅳ-双重校验锁-线程安全"><a href="#Ⅳ-双重校验锁-线程安全" class="headerlink" title="Ⅳ 双重校验锁-线程安全"></a>Ⅳ 双重校验锁-线程安全</h4><p>uniqueInstance 只需要被实例化一次，之后就可以直接使用了。加锁操作只需要对实例化那部分的代码进行，只有当 uniqueInstance 没有被实例化时，才需要进行加锁。</p>
<p>双重校验锁先判断 uniqueInstance 是否已经被实例化，如果没有被实例化，那么才对实例化语句进行加锁。</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Singleton</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">volatile</span> <span class="keyword">static</span> Singleton uniqueInstance;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">private</span> <span class="title">Singleton</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> Singleton <span class="title">getUniqueInstance</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">if</span> (uniqueInstance == <span class="keyword">null</span>) &#123;</span><br><span class="line">            <span class="keyword">synchronized</span> (Singleton.class) &#123;</span><br><span class="line">                <span class="keyword">if</span> (uniqueInstance == <span class="keyword">null</span>) &#123;</span><br><span class="line">                    uniqueInstance = <span class="keyword">new</span> Singleton();</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> uniqueInstance;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>考虑下面的实现，也就是只使用了一个 if 语句。在 uniqueInstance == null 的情况下，如果两个线程都执行了 if 语句，那么两个线程都会进入 if 语句块内。虽然在 if 语句块内有加锁操作，但是两个线程都会执行 <code>uniqueInstance = new Singleton();</code> 这条语句，只是先后的问题，那么就会进行两次实例化。因此必须使用双重校验锁，也就是需要使用两个 if 语句：第一个 if 语句用来避免 uniqueInstance 已经被实例化之后的加锁操作，而第二个 if 语句进行了加锁，所以只能有一个线程进入，就不会出现 uniqueInstance == null 时两个线程同时进行实例化操作。</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">if</span> (uniqueInstance == <span class="keyword">null</span>) &#123;</span><br><span class="line">    <span class="keyword">synchronized</span> (Singleton.class) &#123;</span><br><span class="line">        uniqueInstance = <span class="keyword">new</span> Singleton();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>uniqueInstance 采用 volatile 关键字修饰也是很有必要的， <code>uniqueInstance = new Singleton();</code> 这段代码其实是分为三步执行：</p>
<ol>
<li>为 uniqueInstance 分配内存空间</li>
<li>初始化 uniqueInstance</li>
<li>将 uniqueInstance 指向分配的内存地址</li>
</ol>
<p>但是由于 JVM 具有指令重排的特性，执行顺序有可能变成 1&gt;3&gt;2。指令重排在单线程环境下不会出现问题，但是在多线程环境下会导致一个线程获得还没有初始化的实例。例如，线程 T<sub>1</sub> 执行了 1 和 3，此时 T<sub>2</sub> 调用 getUniqueInstance() 后发现 uniqueInstance 不为空，因此返回 uniqueInstance，但此时 uniqueInstance 还未被初始化。</p>
<p>使用 volatile 可以禁止 JVM 的指令重排，保证在多线程环境下也能正常运行。</p>
<h4 id="Ⅴ-静态内部类实现"><a href="#Ⅴ-静态内部类实现" class="headerlink" title="Ⅴ 静态内部类实现"></a>Ⅴ 静态内部类实现</h4><p>当 Singleton 类被加载时，静态内部类 SingletonHolder 没有被加载进内存。只有当调用 <code>getUniqueInstance()</code> 方法从而触发 <code>SingletonHolder.INSTANCE</code> 时 SingletonHolder 才会被加载，此时初始化 INSTANCE 实例，并且 JVM 能确保 INSTANCE 只被实例化一次。</p>
<p>这种方式不仅具有延迟初始化的好处，而且由 JVM 提供了对线程安全的支持。</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Singleton</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">private</span> <span class="title">Singleton</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">static</span> <span class="class"><span class="keyword">class</span> <span class="title">SingletonHolder</span> </span>&#123;</span><br><span class="line">        <span class="keyword">private</span> <span class="keyword">static</span> <span class="keyword">final</span> Singleton INSTANCE = <span class="keyword">new</span> Singleton();</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> Singleton <span class="title">getUniqueInstance</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> SingletonHolder.INSTANCE;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h4 id="Ⅵ-枚举实现"><a href="#Ⅵ-枚举实现" class="headerlink" title="Ⅵ 枚举实现"></a>Ⅵ 枚举实现</h4><figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">enum</span> <span class="title">Singleton</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    INSTANCE;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">private</span> String objName;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> String <span class="title">getObjName</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> objName;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">setObjName</span><span class="params">(String objName)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">this</span>.objName = objName;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 单例测试</span></span><br><span class="line">        Singleton firstSingleton = Singleton.INSTANCE;</span><br><span class="line">        firstSingleton.setObjName(<span class="string">&quot;firstName&quot;</span>);</span><br><span class="line">        System.out.println(firstSingleton.getObjName());</span><br><span class="line">        Singleton secondSingleton = Singleton.INSTANCE;</span><br><span class="line">        secondSingleton.setObjName(<span class="string">&quot;secondName&quot;</span>);</span><br><span class="line">        System.out.println(firstSingleton.getObjName());</span><br><span class="line">        System.out.println(secondSingleton.getObjName());</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 反射获取实例测试</span></span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line">            Singleton[] enumConstants = Singleton.class.getEnumConstants();</span><br><span class="line">            <span class="keyword">for</span> (Singleton enumConstant : enumConstants) &#123;</span><br><span class="line">                System.out.println(enumConstant.getObjName());</span><br><span class="line">            &#125;</span><br><span class="line">        &#125; <span class="keyword">catch</span> (Exception e) &#123;</span><br><span class="line">            e.printStackTrace();</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight html"><table><tr><td class="code"><pre><span class="line">firstName</span><br><span class="line">secondName</span><br><span class="line">secondName</span><br><span class="line">secondName</span><br></pre></td></tr></table></figure>

<p>该实现可以防止反射攻击。在其它实现中，通过 setAccessible() 方法可以将私有构造函数的访问级别设置为 public，然后调用构造函数从而实例化对象，如果要防止这种攻击，需要在构造函数中添加防止多次实例化的代码。该实现是由 JVM 保证只会实例化一次，因此不会出现上述的反射攻击。</p>
<p>该实现在多次序列化和序列化之后，不会得到多个实例。而其它实现需要使用 transient 修饰所有字段，并且实现序列化和反序列化的方法。</p>
<h3 id="Examples"><a href="#Examples" class="headerlink" title="Examples"></a>Examples</h3><ul>
<li>Logger Classes</li>
<li>Configuration Classes</li>
<li>Accesing resources in shared mode</li>
<li>Factories implemented as Singletons</li>
</ul>
<h3 id="JDK"><a href="#JDK" class="headerlink" title="JDK"></a>JDK</h3><ul>
<li><a target="_blank" rel="noopener" href="http://docs.oracle.com/javase/8/docs/api/java/lang/Runtime.html#getRuntime%28%29">java.lang.Runtime#getRuntime()</a></li>
<li><a target="_blank" rel="noopener" href="http://docs.oracle.com/javase/8/docs/api/java/awt/Desktop.html#getDesktop--">java.awt.Desktop#getDesktop()</a></li>
<li><a target="_blank" rel="noopener" href="http://docs.oracle.com/javase/8/docs/api/java/lang/System.html#getSecurityManager--">java.lang.System#getSecurityManager()</a></li>
</ul>
<h2 id="2-简单工厂（Simple-Factory）"><a href="#2-简单工厂（Simple-Factory）" class="headerlink" title="2. 简单工厂（Simple Factory）"></a>2. 简单工厂（Simple Factory）</h2><h3 id="Intent-1"><a href="#Intent-1" class="headerlink" title="Intent"></a>Intent</h3><p>在创建一个对象时不向客户暴露内部细节，并提供一个创建对象的通用接口。</p>
<h3 id="Class-Diagram-1"><a href="#Class-Diagram-1" class="headerlink" title="Class Diagram"></a>Class Diagram</h3><p>简单工厂把实例化的操作单独放到一个类中，这个类就成为简单工厂类，让简单工厂类来决定应该用哪个具体子类来实例化。</p>
<p>这样做能把客户类和具体子类的实现解耦，客户类不再需要知道有哪些子类以及应当实例化哪个子类。客户类往往有多个，如果不使用简单工厂，那么所有的客户类都要知道所有子类的细节。而且一旦子类发生改变，例如增加子类，那么所有的客户类都要进行修改。</p>
<div align="center"> <img src= "" data-lazy-src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/40c0c17e-bba6-4493-9857-147c0044a018.png"/> </div><br>

<h3 id="Implementation-1"><a href="#Implementation-1" class="headerlink" title="Implementation"></a>Implementation</h3><figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">interface</span> <span class="title">Product</span> </span>&#123;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">ConcreteProduct</span> <span class="keyword">implements</span> <span class="title">Product</span> </span>&#123;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">ConcreteProduct1</span> <span class="keyword">implements</span> <span class="title">Product</span> </span>&#123;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">ConcreteProduct2</span> <span class="keyword">implements</span> <span class="title">Product</span> </span>&#123;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>以下的 Client 类包含了实例化的代码，这是一种错误的实现。如果在客户类中存在这种实例化代码，就需要考虑将代码放到简单工厂中。</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Client</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">int</span> type = <span class="number">1</span>;</span><br><span class="line">        Product product;</span><br><span class="line">        <span class="keyword">if</span> (type == <span class="number">1</span>) &#123;</span><br><span class="line">            product = <span class="keyword">new</span> ConcreteProduct1();</span><br><span class="line">        &#125; <span class="keyword">else</span> <span class="keyword">if</span> (type == <span class="number">2</span>) &#123;</span><br><span class="line">            product = <span class="keyword">new</span> ConcreteProduct2();</span><br><span class="line">        &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">            product = <span class="keyword">new</span> ConcreteProduct();</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="comment">// do something with the product</span></span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>以下的 SimpleFactory 是简单工厂实现，它被所有需要进行实例化的客户类调用。</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">SimpleFactory</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> Product <span class="title">createProduct</span><span class="params">(<span class="keyword">int</span> type)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">if</span> (type == <span class="number">1</span>) &#123;</span><br><span class="line">            <span class="keyword">return</span> <span class="keyword">new</span> ConcreteProduct1();</span><br><span class="line">        &#125; <span class="keyword">else</span> <span class="keyword">if</span> (type == <span class="number">2</span>) &#123;</span><br><span class="line">            <span class="keyword">return</span> <span class="keyword">new</span> ConcreteProduct2();</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">new</span> ConcreteProduct();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Client</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">        SimpleFactory simpleFactory = <span class="keyword">new</span> SimpleFactory();</span><br><span class="line">        Product product = simpleFactory.createProduct(<span class="number">1</span>);</span><br><span class="line">        <span class="comment">// do something with the product</span></span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="3-工厂方法（Factory-Method）"><a href="#3-工厂方法（Factory-Method）" class="headerlink" title="3. 工厂方法（Factory Method）"></a>3. 工厂方法（Factory Method）</h2><h3 id="Intent-2"><a href="#Intent-2" class="headerlink" title="Intent"></a>Intent</h3><p>定义了一个创建对象的接口，但由子类决定要实例化哪个类。工厂方法把实例化操作推迟到子类。</p>
<h3 id="Class-Diagram-2"><a href="#Class-Diagram-2" class="headerlink" title="Class Diagram"></a>Class Diagram</h3><p>在简单工厂中，创建对象的是另一个类，而在工厂方法中，是由子类来创建对象。</p>
<p>下图中，Factory 有一个 doSomething() 方法，这个方法需要用到一个产品对象，这个产品对象由 factoryMethod() 方法创建。该方法是抽象的，需要由子类去实现。</p>
<div align="center"> <img src= "" data-lazy-src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/f4d0afd0-8e78-4914-9e60-4366eaf065b5.png"/> </div><br>

<h3 id="Implementation-2"><a href="#Implementation-2" class="headerlink" title="Implementation"></a>Implementation</h3><figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">abstract</span> <span class="class"><span class="keyword">class</span> <span class="title">Factory</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">abstract</span> <span class="keyword">public</span> Product <span class="title">factoryMethod</span><span class="params">()</span></span>;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">doSomething</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        Product product = factoryMethod();</span><br><span class="line">        <span class="comment">// do something with the product</span></span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">ConcreteFactory</span> <span class="keyword">extends</span> <span class="title">Factory</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> Product <span class="title">factoryMethod</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">new</span> ConcreteProduct();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">ConcreteFactory1</span> <span class="keyword">extends</span> <span class="title">Factory</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> Product <span class="title">factoryMethod</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">new</span> ConcreteProduct1();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">ConcreteFactory2</span> <span class="keyword">extends</span> <span class="title">Factory</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> Product <span class="title">factoryMethod</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">new</span> ConcreteProduct2();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h3 id="JDK-1"><a href="#JDK-1" class="headerlink" title="JDK"></a>JDK</h3><ul>
<li><a target="_blank" rel="noopener" href="http://docs.oracle.com/javase/8/docs/api/java/util/Calendar.html#getInstance--">java.util.Calendar</a></li>
<li><a target="_blank" rel="noopener" href="http://docs.oracle.com/javase/8/docs/api/java/util/ResourceBundle.html#getBundle-java.lang.String-">java.util.ResourceBundle</a></li>
<li><a target="_blank" rel="noopener" href="http://docs.oracle.com/javase/8/docs/api/java/text/NumberFormat.html#getInstance--">java.text.NumberFormat</a></li>
<li><a target="_blank" rel="noopener" href="http://docs.oracle.com/javase/8/docs/api/java/nio/charset/Charset.html#forName-java.lang.String-">java.nio.charset.Charset</a></li>
<li><a target="_blank" rel="noopener" href="http://docs.oracle.com/javase/8/docs/api/java/net/URLStreamHandlerFactory.html#createURLStreamHandler-java.lang.String-">java.net.URLStreamHandlerFactory</a></li>
<li><a target="_blank" rel="noopener" href="https://docs.oracle.com/javase/8/docs/api/java/util/EnumSet.html#of-E-">java.util.EnumSet</a></li>
<li><a target="_blank" rel="noopener" href="https://docs.oracle.com/javase/8/docs/api/javax/xml/bind/JAXBContext.html#createMarshaller--">javax.xml.bind.JAXBContext</a></li>
</ul>
<h2 id="4-抽象工厂（Abstract-Factory）"><a href="#4-抽象工厂（Abstract-Factory）" class="headerlink" title="4. 抽象工厂（Abstract Factory）"></a>4. 抽象工厂（Abstract Factory）</h2><h3 id="Intent-3"><a href="#Intent-3" class="headerlink" title="Intent"></a>Intent</h3><p>提供一个接口，用于创建   <strong>相关的对象家族</strong>  。</p>
<h3 id="Class-Diagram-3"><a href="#Class-Diagram-3" class="headerlink" title="Class Diagram"></a>Class Diagram</h3><p>抽象工厂模式创建的是对象家族，也就是很多对象而不是一个对象，并且这些对象是相关的，也就是说必须一起创建出来。而工厂方法模式只是用于创建一个对象，这和抽象工厂模式有很大不同。</p>
<p>抽象工厂模式用到了工厂方法模式来创建单一对象，AbstractFactory 中的 createProductA() 和 createProductB() 方法都是让子类来实现，这两个方法单独来看就是在创建一个对象，这符合工厂方法模式的定义。</p>
<p>至于创建对象的家族这一概念是在 Client 体现，Client 要通过 AbstractFactory 同时调用两个方法来创建出两个对象，在这里这两个对象就有很大的相关性，Client 需要同时创建出这两个对象。</p>
<p>从高层次来看，抽象工厂使用了组合，即 Cilent 组合了 AbstractFactory，而工厂方法模式使用了继承。</p>
<div align="center"> <img src= "" data-lazy-src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/e2190c36-8b27-4690-bde5-9911020a1294.png"/> </div><br>

<h3 id="Implementation-3"><a href="#Implementation-3" class="headerlink" title="Implementation"></a>Implementation</h3><figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">AbstractProductA</span> </span>&#123;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">AbstractProductB</span> </span>&#123;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">ProductA1</span> <span class="keyword">extends</span> <span class="title">AbstractProductA</span> </span>&#123;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">ProductA2</span> <span class="keyword">extends</span> <span class="title">AbstractProductA</span> </span>&#123;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">ProductB1</span> <span class="keyword">extends</span> <span class="title">AbstractProductB</span> </span>&#123;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">ProductB2</span> <span class="keyword">extends</span> <span class="title">AbstractProductB</span> </span>&#123;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">abstract</span> <span class="class"><span class="keyword">class</span> <span class="title">AbstractFactory</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">abstract</span> AbstractProductA <span class="title">createProductA</span><span class="params">()</span></span>;</span><br><span class="line">    <span class="function"><span class="keyword">abstract</span> AbstractProductB <span class="title">createProductB</span><span class="params">()</span></span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">ConcreteFactory1</span> <span class="keyword">extends</span> <span class="title">AbstractFactory</span> </span>&#123;</span><br><span class="line">    <span class="function">AbstractProductA <span class="title">createProductA</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">new</span> ProductA1();</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function">AbstractProductB <span class="title">createProductB</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">new</span> ProductB1();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">ConcreteFactory2</span> <span class="keyword">extends</span> <span class="title">AbstractFactory</span> </span>&#123;</span><br><span class="line">    <span class="function">AbstractProductA <span class="title">createProductA</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">new</span> ProductA2();</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function">AbstractProductB <span class="title">createProductB</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">new</span> ProductB2();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Client</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">        AbstractFactory abstractFactory = <span class="keyword">new</span> ConcreteFactory1();</span><br><span class="line">        AbstractProductA productA = abstractFactory.createProductA();</span><br><span class="line">        AbstractProductB productB = abstractFactory.createProductB();</span><br><span class="line">        <span class="comment">// do something with productA and productB</span></span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h3 id="JDK-2"><a href="#JDK-2" class="headerlink" title="JDK"></a>JDK</h3><ul>
<li><a target="_blank" rel="noopener" href="http://docs.oracle.com/javase/8/docs/api/javax/xml/parsers/DocumentBuilderFactory.html">javax.xml.parsers.DocumentBuilderFactory</a></li>
<li><a target="_blank" rel="noopener" href="http://docs.oracle.com/javase/8/docs/api/javax/xml/transform/TransformerFactory.html#newInstance--">javax.xml.transform.TransformerFactory</a></li>
<li><a target="_blank" rel="noopener" href="http://docs.oracle.com/javase/8/docs/api/javax/xml/xpath/XPathFactory.html#newInstance--">javax.xml.xpath.XPathFactory</a></li>
</ul>
<h2 id="5-生成器（Builder）"><a href="#5-生成器（Builder）" class="headerlink" title="5. 生成器（Builder）"></a>5. 生成器（Builder）</h2><h3 id="Intent-4"><a href="#Intent-4" class="headerlink" title="Intent"></a>Intent</h3><p>封装一个对象的构造过程，并允许按步骤构造。</p>
<h3 id="Class-Diagram-4"><a href="#Class-Diagram-4" class="headerlink" title="Class Diagram"></a>Class Diagram</h3><div align="center"> <img src= "" data-lazy-src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/db5e376d-0b3e-490e-a43a-3231914b6668.png"/> </div><br>

<h3 id="Implementation-4"><a href="#Implementation-4" class="headerlink" title="Implementation"></a>Implementation</h3><p>以下是一个简易的 StringBuilder 实现，参考了 JDK 1.8 源码。</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">AbstractStringBuilder</span> </span>&#123;</span><br><span class="line">    <span class="keyword">protected</span> <span class="keyword">char</span>[] value;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">protected</span> <span class="keyword">int</span> count;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="title">AbstractStringBuilder</span><span class="params">(<span class="keyword">int</span> capacity)</span> </span>&#123;</span><br><span class="line">        count = <span class="number">0</span>;</span><br><span class="line">        value = <span class="keyword">new</span> <span class="keyword">char</span>[capacity];</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> AbstractStringBuilder <span class="title">append</span><span class="params">(<span class="keyword">char</span> c)</span> </span>&#123;</span><br><span class="line">        ensureCapacityInternal(count + <span class="number">1</span>);</span><br><span class="line">        value[count++] = c;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">this</span>;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">private</span> <span class="keyword">void</span> <span class="title">ensureCapacityInternal</span><span class="params">(<span class="keyword">int</span> minimumCapacity)</span> </span>&#123;</span><br><span class="line">        <span class="comment">// overflow-conscious code</span></span><br><span class="line">        <span class="keyword">if</span> (minimumCapacity - value.length &gt; <span class="number">0</span>)</span><br><span class="line">            expandCapacity(minimumCapacity);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">void</span> <span class="title">expandCapacity</span><span class="params">(<span class="keyword">int</span> minimumCapacity)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">int</span> newCapacity = value.length * <span class="number">2</span> + <span class="number">2</span>;</span><br><span class="line">        <span class="keyword">if</span> (newCapacity - minimumCapacity &lt; <span class="number">0</span>)</span><br><span class="line">            newCapacity = minimumCapacity;</span><br><span class="line">        <span class="keyword">if</span> (newCapacity &lt; <span class="number">0</span>) &#123;</span><br><span class="line">            <span class="keyword">if</span> (minimumCapacity &lt; <span class="number">0</span>) <span class="comment">// overflow</span></span><br><span class="line">                <span class="keyword">throw</span> <span class="keyword">new</span> OutOfMemoryError();</span><br><span class="line">            newCapacity = Integer.MAX_VALUE;</span><br><span class="line">        &#125;</span><br><span class="line">        value = Arrays.copyOf(value, newCapacity);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">StringBuilder</span> <span class="keyword">extends</span> <span class="title">AbstractStringBuilder</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="title">StringBuilder</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">super</span>(<span class="number">16</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> String <span class="title">toString</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="comment">// Create a copy, don&#x27;t share the array</span></span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">new</span> String(value, <span class="number">0</span>, count);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Client</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">        StringBuilder sb = <span class="keyword">new</span> StringBuilder();</span><br><span class="line">        <span class="keyword">final</span> <span class="keyword">int</span> count = <span class="number">26</span>;</span><br><span class="line">        <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i &lt; count; i++) &#123;</span><br><span class="line">            sb.append((<span class="keyword">char</span>) (<span class="string">&#x27;a&#x27;</span> + i));</span><br><span class="line">        &#125;</span><br><span class="line">        System.out.println(sb.toString());</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight html"><table><tr><td class="code"><pre><span class="line">abcdefghijklmnopqrstuvwxyz</span><br></pre></td></tr></table></figure>

<h3 id="JDK-3"><a href="#JDK-3" class="headerlink" title="JDK"></a>JDK</h3><ul>
<li><a target="_blank" rel="noopener" href="http://docs.oracle.com/javase/8/docs/api/java/lang/StringBuilder.html">java.lang.StringBuilder</a></li>
<li><a target="_blank" rel="noopener" href="http://docs.oracle.com/javase/8/docs/api/java/nio/ByteBuffer.html#put-byte-">java.nio.ByteBuffer</a></li>
<li><a target="_blank" rel="noopener" href="http://docs.oracle.com/javase/8/docs/api/java/lang/StringBuffer.html#append-boolean-">java.lang.StringBuffer</a></li>
<li><a target="_blank" rel="noopener" href="http://docs.oracle.com/javase/8/docs/api/java/lang/Appendable.html">java.lang.Appendable</a></li>
<li><a target="_blank" rel="noopener" href="https://github.com/apache/camel/tree/0e195428ee04531be27a0b659005e3aa8d159d23/camel-core/src/main/java/org/apache/camel/builder">Apache Camel builders</a></li>
</ul>
<h2 id="6-原型模式（Prototype）"><a href="#6-原型模式（Prototype）" class="headerlink" title="6. 原型模式（Prototype）"></a>6. 原型模式（Prototype）</h2><h3 id="Intent-5"><a href="#Intent-5" class="headerlink" title="Intent"></a>Intent</h3><p>使用原型实例指定要创建对象的类型，通过复制这个原型来创建新对象。</p>
<h3 id="Class-Diagram-5"><a href="#Class-Diagram-5" class="headerlink" title="Class Diagram"></a>Class Diagram</h3><div align="center"> <img src= "" data-lazy-src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/b8922f8c-95e6-4187-be85-572a509afb71.png"/> </div><br>

<h3 id="Implementation-5"><a href="#Implementation-5" class="headerlink" title="Implementation"></a>Implementation</h3><figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">abstract</span> <span class="class"><span class="keyword">class</span> <span class="title">Prototype</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">abstract</span> Prototype <span class="title">myClone</span><span class="params">()</span></span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">ConcretePrototype</span> <span class="keyword">extends</span> <span class="title">Prototype</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">private</span> String filed;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="title">ConcretePrototype</span><span class="params">(String filed)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">this</span>.filed = filed;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function">Prototype <span class="title">myClone</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">new</span> ConcretePrototype(filed);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> String <span class="title">toString</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> filed;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Client</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">        Prototype prototype = <span class="keyword">new</span> ConcretePrototype(<span class="string">&quot;abc&quot;</span>);</span><br><span class="line">        Prototype clone = prototype.myClone();</span><br><span class="line">        System.out.println(clone.toString());</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight html"><table><tr><td class="code"><pre><span class="line">abc</span><br></pre></td></tr></table></figure>

<h3 id="JDK-4"><a href="#JDK-4" class="headerlink" title="JDK"></a>JDK</h3><ul>
<li><a target="_blank" rel="noopener" href="http://docs.oracle.com/javase/8/docs/api/java/lang/Object.html#clone%28%29">java.lang.Object#clone()</a></li>
</ul>
<h1 id="三、行为型"><a href="#三、行为型" class="headerlink" title="三、行为型"></a>三、行为型</h1><h2 id="1-责任链（Chain-Of-Responsibility）"><a href="#1-责任链（Chain-Of-Responsibility）" class="headerlink" title="1. 责任链（Chain Of Responsibility）"></a>1. 责任链（Chain Of Responsibility）</h2><h3 id="Intent-6"><a href="#Intent-6" class="headerlink" title="Intent"></a>Intent</h3><p>使多个对象都有机会处理请求，从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链，并沿着这条链发送该请求，直到有一个对象处理它为止。</p>
<h3 id="Class-Diagram-6"><a href="#Class-Diagram-6" class="headerlink" title="Class Diagram"></a>Class Diagram</h3><ul>
<li>Handler：定义处理请求的接口，并且实现后继链（successor）</li>
</ul>
<div align="center"> <img src= "" data-lazy-src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/ca9f23bf-55a4-47b2-9534-a28e35397988.png"/> </div><br>

<h3 id="Implementation-6"><a href="#Implementation-6" class="headerlink" title="Implementation"></a>Implementation</h3><figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">abstract</span> <span class="class"><span class="keyword">class</span> <span class="title">Handler</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">protected</span> Handler successor;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="title">Handler</span><span class="params">(Handler successor)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">this</span>.successor = successor;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">protected</span> <span class="keyword">abstract</span> <span class="keyword">void</span> <span class="title">handleRequest</span><span class="params">(Request request)</span></span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">ConcreteHandler1</span> <span class="keyword">extends</span> <span class="title">Handler</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="title">ConcreteHandler1</span><span class="params">(Handler successor)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">super</span>(successor);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">protected</span> <span class="keyword">void</span> <span class="title">handleRequest</span><span class="params">(Request request)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">if</span> (request.getType() == RequestType.TYPE1) &#123;</span><br><span class="line">            System.out.println(request.getName() + <span class="string">&quot; is handle by ConcreteHandler1&quot;</span>);</span><br><span class="line">            <span class="keyword">return</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span> (successor != <span class="keyword">null</span>) &#123;</span><br><span class="line">            successor.handleRequest(request);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">ConcreteHandler2</span> <span class="keyword">extends</span> <span class="title">Handler</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="title">ConcreteHandler2</span><span class="params">(Handler successor)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">super</span>(successor);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">protected</span> <span class="keyword">void</span> <span class="title">handleRequest</span><span class="params">(Request request)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">if</span> (request.getType() == RequestType.TYPE2) &#123;</span><br><span class="line">            System.out.println(request.getName() + <span class="string">&quot; is handle by ConcreteHandler2&quot;</span>);</span><br><span class="line">            <span class="keyword">return</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span> (successor != <span class="keyword">null</span>) &#123;</span><br><span class="line">            successor.handleRequest(request);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Request</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">private</span> RequestType type;</span><br><span class="line">    <span class="keyword">private</span> String name;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="title">Request</span><span class="params">(RequestType type, String name)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">this</span>.type = type;</span><br><span class="line">        <span class="keyword">this</span>.name = name;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> RequestType <span class="title">getType</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> type;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> String <span class="title">getName</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> name;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">enum</span> <span class="title">RequestType</span> </span>&#123;</span><br><span class="line">    TYPE1, TYPE2</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Client</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">        Handler handler1 = <span class="keyword">new</span> ConcreteHandler1(<span class="keyword">null</span>);</span><br><span class="line">        Handler handler2 = <span class="keyword">new</span> ConcreteHandler2(handler1);</span><br><span class="line"></span><br><span class="line">        Request request1 = <span class="keyword">new</span> Request(RequestType.TYPE1, <span class="string">&quot;request1&quot;</span>);</span><br><span class="line">        handler2.handleRequest(request1);</span><br><span class="line"></span><br><span class="line">        Request request2 = <span class="keyword">new</span> Request(RequestType.TYPE2, <span class="string">&quot;request2&quot;</span>);</span><br><span class="line">        handler2.handleRequest(request2);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight html"><table><tr><td class="code"><pre><span class="line">request1 is handle by ConcreteHandler1</span><br><span class="line">request2 is handle by ConcreteHandler2</span><br></pre></td></tr></table></figure>

<h3 id="JDK-5"><a href="#JDK-5" class="headerlink" title="JDK"></a>JDK</h3><ul>
<li><a target="_blank" rel="noopener" href="http://docs.oracle.com/javase/8/docs/api/java/util/logging/Logger.html#log%28java.util.logging.Level,%20java.lang.String%29">java.util.logging.Logger#log()</a></li>
<li><a target="_blank" rel="noopener" href="https://commons.apache.org/proper/commons-chain/index.html">Apache Commons Chain</a></li>
<li><a target="_blank" rel="noopener" href="http://docs.oracle.com/javaee/7/api/javax/servlet/Filter.html#doFilter-javax.servlet.ServletRequest-javax.servlet.ServletResponse-javax.servlet.FilterChain-">javax.servlet.Filter#doFilter()</a></li>
</ul>
<h2 id="2-命令（Command）"><a href="#2-命令（Command）" class="headerlink" title="2. 命令（Command）"></a>2. 命令（Command）</h2><h3 id="Intent-7"><a href="#Intent-7" class="headerlink" title="Intent"></a>Intent</h3><p>将命令封装成对象中，具有以下作用：</p>
<ul>
<li>使用命令来参数化其它对象</li>
<li>将命令放入队列中进行排队</li>
<li>将命令的操作记录到日志中</li>
<li>支持可撤销的操作</li>
</ul>
<h3 id="Class-Diagram-7"><a href="#Class-Diagram-7" class="headerlink" title="Class Diagram"></a>Class Diagram</h3><ul>
<li>Command：命令</li>
<li>Receiver：命令接收者，也就是命令真正的执行者</li>
<li>Invoker：通过它来调用命令</li>
<li>Client：可以设置命令与命令的接收者</li>
</ul>
<div align="center"> <img src= "" data-lazy-src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/c44a0342-f405-4f17-b750-e27cf4aadde2.png"/> </div><br>

<h3 id="Implementation-7"><a href="#Implementation-7" class="headerlink" title="Implementation"></a>Implementation</h3><p>设计一个遥控器，可以控制电灯开关。</p>
<div align="center"> <img src= "" data-lazy-src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/e6bded8e-41a0-489a-88a6-638e88ab7666.jpg"/> </div><br>

<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">interface</span> <span class="title">Command</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">void</span> <span class="title">execute</span><span class="params">()</span></span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">LightOnCommand</span> <span class="keyword">implements</span> <span class="title">Command</span> </span>&#123;</span><br><span class="line">    Light light;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="title">LightOnCommand</span><span class="params">(Light light)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">this</span>.light = light;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">execute</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        light.on();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">LightOffCommand</span> <span class="keyword">implements</span> <span class="title">Command</span> </span>&#123;</span><br><span class="line">    Light light;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="title">LightOffCommand</span><span class="params">(Light light)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">this</span>.light = light;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">execute</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        light.off();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Light</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">on</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;Light is on!&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">off</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;Light is off!&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 遥控器</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Invoker</span> </span>&#123;</span><br><span class="line">    <span class="keyword">private</span> Command[] onCommands;</span><br><span class="line">    <span class="keyword">private</span> Command[] offCommands;</span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">final</span> <span class="keyword">int</span> slotNum = <span class="number">7</span>;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="title">Invoker</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">this</span>.onCommands = <span class="keyword">new</span> Command[slotNum];</span><br><span class="line">        <span class="keyword">this</span>.offCommands = <span class="keyword">new</span> Command[slotNum];</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">setOnCommand</span><span class="params">(Command command, <span class="keyword">int</span> slot)</span> </span>&#123;</span><br><span class="line">        onCommands[slot] = command;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">setOffCommand</span><span class="params">(Command command, <span class="keyword">int</span> slot)</span> </span>&#123;</span><br><span class="line">        offCommands[slot] = command;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onButtonWasPushed</span><span class="params">(<span class="keyword">int</span> slot)</span> </span>&#123;</span><br><span class="line">        onCommands[slot].execute();</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">offButtonWasPushed</span><span class="params">(<span class="keyword">int</span> slot)</span> </span>&#123;</span><br><span class="line">        offCommands[slot].execute();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Client</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">        Invoker invoker = <span class="keyword">new</span> Invoker();</span><br><span class="line">        Light light = <span class="keyword">new</span> Light();</span><br><span class="line">        Command lightOnCommand = <span class="keyword">new</span> LightOnCommand(light);</span><br><span class="line">        Command lightOffCommand = <span class="keyword">new</span> LightOffCommand(light);</span><br><span class="line">        invoker.setOnCommand(lightOnCommand, <span class="number">0</span>);</span><br><span class="line">        invoker.setOffCommand(lightOffCommand, <span class="number">0</span>);</span><br><span class="line">        invoker.onButtonWasPushed(<span class="number">0</span>);</span><br><span class="line">        invoker.offButtonWasPushed(<span class="number">0</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h3 id="JDK-6"><a href="#JDK-6" class="headerlink" title="JDK"></a>JDK</h3><ul>
<li><a target="_blank" rel="noopener" href="http://docs.oracle.com/javase/8/docs/api/java/lang/Runnable.html">java.lang.Runnable</a></li>
<li><a target="_blank" rel="noopener" href="https://github.com/Netflix/Hystrix/wiki">Netflix Hystrix</a></li>
<li><a target="_blank" rel="noopener" href="http://docs.oracle.com/javase/8/docs/api/javax/swing/Action.html">javax.swing.Action</a></li>
</ul>
<h2 id="3-解释器（Interpreter）"><a href="#3-解释器（Interpreter）" class="headerlink" title="3. 解释器（Interpreter）"></a>3. 解释器（Interpreter）</h2><h3 id="Intent-8"><a href="#Intent-8" class="headerlink" title="Intent"></a>Intent</h3><p>为语言创建解释器，通常由语言的语法和语法分析来定义。</p>
<h3 id="Class-Diagram-8"><a href="#Class-Diagram-8" class="headerlink" title="Class Diagram"></a>Class Diagram</h3><ul>
<li>TerminalExpression：终结符表达式，每个终结符都需要一个 TerminalExpression。</li>
<li>Context：上下文，包含解释器之外的一些全局信息。</li>
</ul>
<div align="center"> <img src= "" data-lazy-src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/2b125bcd-1b36-43be-9b78-d90b076be549.png"/> </div><br>

<h3 id="Implementation-8"><a href="#Implementation-8" class="headerlink" title="Implementation"></a>Implementation</h3><p>以下是一个规则检验器实现，具有 and 和 or 规则，通过规则可以构建一颗解析树，用来检验一个文本是否满足解析树定义的规则。</p>
<p>例如一颗解析树为 D And (A Or (B C))，文本 “D A” 满足该解析树定义的规则。</p>
<p>这里的 Context 指的是 String。</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">abstract</span> <span class="class"><span class="keyword">class</span> <span class="title">Expression</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">abstract</span> <span class="keyword">boolean</span> <span class="title">interpret</span><span class="params">(String str)</span></span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">TerminalExpression</span> <span class="keyword">extends</span> <span class="title">Expression</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">private</span> String literal = <span class="keyword">null</span>;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="title">TerminalExpression</span><span class="params">(String str)</span> </span>&#123;</span><br><span class="line">        literal = str;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">interpret</span><span class="params">(String str)</span> </span>&#123;</span><br><span class="line">        StringTokenizer st = <span class="keyword">new</span> StringTokenizer(str);</span><br><span class="line">        <span class="keyword">while</span> (st.hasMoreTokens()) &#123;</span><br><span class="line">            String test = st.nextToken();</span><br><span class="line">            <span class="keyword">if</span> (test.equals(literal)) &#123;</span><br><span class="line">                <span class="keyword">return</span> <span class="keyword">true</span>;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">false</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">AndExpression</span> <span class="keyword">extends</span> <span class="title">Expression</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">private</span> Expression expression1 = <span class="keyword">null</span>;</span><br><span class="line">    <span class="keyword">private</span> Expression expression2 = <span class="keyword">null</span>;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="title">AndExpression</span><span class="params">(Expression expression1, Expression expression2)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">this</span>.expression1 = expression1;</span><br><span class="line">        <span class="keyword">this</span>.expression2 = expression2;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">interpret</span><span class="params">(String str)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> expression1.interpret(str) &amp;&amp; expression2.interpret(str);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">OrExpression</span> <span class="keyword">extends</span> <span class="title">Expression</span> </span>&#123;</span><br><span class="line">    <span class="keyword">private</span> Expression expression1 = <span class="keyword">null</span>;</span><br><span class="line">    <span class="keyword">private</span> Expression expression2 = <span class="keyword">null</span>;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="title">OrExpression</span><span class="params">(Expression expression1, Expression expression2)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">this</span>.expression1 = expression1;</span><br><span class="line">        <span class="keyword">this</span>.expression2 = expression2;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">interpret</span><span class="params">(String str)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> expression1.interpret(str) || expression2.interpret(str);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Client</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 构建解析树</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> Expression <span class="title">buildInterpreterTree</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="comment">// Literal</span></span><br><span class="line">        Expression terminal1 = <span class="keyword">new</span> TerminalExpression(<span class="string">&quot;A&quot;</span>);</span><br><span class="line">        Expression terminal2 = <span class="keyword">new</span> TerminalExpression(<span class="string">&quot;B&quot;</span>);</span><br><span class="line">        Expression terminal3 = <span class="keyword">new</span> TerminalExpression(<span class="string">&quot;C&quot;</span>);</span><br><span class="line">        Expression terminal4 = <span class="keyword">new</span> TerminalExpression(<span class="string">&quot;D&quot;</span>);</span><br><span class="line">        <span class="comment">// B C</span></span><br><span class="line">        Expression alternation1 = <span class="keyword">new</span> OrExpression(terminal2, terminal3);</span><br><span class="line">        <span class="comment">// A Or (B C)</span></span><br><span class="line">        Expression alternation2 = <span class="keyword">new</span> OrExpression(terminal1, alternation1);</span><br><span class="line">        <span class="comment">// D And (A Or (B C))</span></span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">new</span> AndExpression(terminal4, alternation2);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">        Expression define = buildInterpreterTree();</span><br><span class="line">        String context1 = <span class="string">&quot;D A&quot;</span>;</span><br><span class="line">        String context2 = <span class="string">&quot;A B&quot;</span>;</span><br><span class="line">        System.out.println(define.interpret(context1));</span><br><span class="line">        System.out.println(define.interpret(context2));</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight html"><table><tr><td class="code"><pre><span class="line">true</span><br><span class="line">false</span><br></pre></td></tr></table></figure>

<h3 id="JDK-7"><a href="#JDK-7" class="headerlink" title="JDK"></a>JDK</h3><ul>
<li><a target="_blank" rel="noopener" href="http://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html">java.util.Pattern</a></li>
<li><a target="_blank" rel="noopener" href="http://docs.oracle.com/javase/8/docs/api/java/text/Normalizer.html">java.text.Normalizer</a></li>
<li>All subclasses of <a target="_blank" rel="noopener" href="http://docs.oracle.com/javase/8/docs/api/java/text/Format.html">java.text.Format</a></li>
<li><a target="_blank" rel="noopener" href="http://docs.oracle.com/javaee/7/api/javax/el/ELResolver.html">javax.el.ELResolver</a></li>
</ul>
<h2 id="4-迭代器（Iterator）"><a href="#4-迭代器（Iterator）" class="headerlink" title="4. 迭代器（Iterator）"></a>4. 迭代器（Iterator）</h2><h3 id="Intent-9"><a href="#Intent-9" class="headerlink" title="Intent"></a>Intent</h3><p>提供一种顺序访问聚合对象元素的方法，并且不暴露聚合对象的内部表示。</p>
<h3 id="Class-Diagram-9"><a href="#Class-Diagram-9" class="headerlink" title="Class Diagram"></a>Class Diagram</h3><ul>
<li>Aggregate 是聚合类，其中 createIterator() 方法可以产生一个 Iterator；</li>
<li>Iterator 主要定义了 hasNext() 和 next() 方法。</li>
<li>Client 组合了 Aggregate，为了迭代遍历 Aggregate，也需要组合 Iterator。</li>
</ul>
<div align="center"> <img src= "" data-lazy-src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/89292ae1-5f13-44dc-b508-3f035e80bf89.png"/> </div><br>

<h3 id="Implementation-9"><a href="#Implementation-9" class="headerlink" title="Implementation"></a>Implementation</h3><figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">interface</span> <span class="title">Aggregate</span> </span>&#123;</span><br><span class="line">    <span class="function">Iterator <span class="title">createIterator</span><span class="params">()</span></span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">ConcreteAggregate</span> <span class="keyword">implements</span> <span class="title">Aggregate</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">private</span> Integer[] items;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="title">ConcreteAggregate</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        items = <span class="keyword">new</span> Integer[<span class="number">10</span>];</span><br><span class="line">        <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i &lt; items.length; i++) &#123;</span><br><span class="line">            items[i] = i;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> Iterator <span class="title">createIterator</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">new</span> ConcreteIterator&lt;Integer&gt;(items);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">interface</span> <span class="title">Iterator</span>&lt;<span class="title">Item</span>&gt; </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="function">Item <span class="title">next</span><span class="params">()</span></span>;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">boolean</span> <span class="title">hasNext</span><span class="params">()</span></span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">ConcreteIterator</span>&lt;<span class="title">Item</span>&gt; <span class="keyword">implements</span> <span class="title">Iterator</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">private</span> Item[] items;</span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">int</span> position = <span class="number">0</span>;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="title">ConcreteIterator</span><span class="params">(Item[] items)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">this</span>.items = items;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> Object <span class="title">next</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> items[position++];</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">hasNext</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> position &lt; items.length;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Client</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">        Aggregate aggregate = <span class="keyword">new</span> ConcreteAggregate();</span><br><span class="line">        Iterator&lt;Integer&gt; iterator = aggregate.createIterator();</span><br><span class="line">        <span class="keyword">while</span> (iterator.hasNext()) &#123;</span><br><span class="line">            System.out.println(iterator.next());</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h3 id="JDK-8"><a href="#JDK-8" class="headerlink" title="JDK"></a>JDK</h3><ul>
<li><a target="_blank" rel="noopener" href="http://docs.oracle.com/javase/8/docs/api/java/util/Iterator.html">java.util.Iterator</a></li>
<li><a target="_blank" rel="noopener" href="http://docs.oracle.com/javase/8/docs/api/java/util/Enumeration.html">java.util.Enumeration</a></li>
</ul>
<h2 id="5-中介者（Mediator）"><a href="#5-中介者（Mediator）" class="headerlink" title="5. 中介者（Mediator）"></a>5. 中介者（Mediator）</h2><h3 id="Intent-10"><a href="#Intent-10" class="headerlink" title="Intent"></a>Intent</h3><p>集中相关对象之间复杂的沟通和控制方式。</p>
<h3 id="Class-Diagram-10"><a href="#Class-Diagram-10" class="headerlink" title="Class Diagram"></a>Class Diagram</h3><ul>
<li>Mediator：中介者，定义一个接口用于与各同事（Colleague）对象通信。</li>
<li>Colleague：同事，相关对象</li>
</ul>
<div align="center"> <img src= "" data-lazy-src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/30d6e95c-2e3c-4d32-bf4f-68128a70bc05.png"/> </div><br>

<h3 id="Implementation-10"><a href="#Implementation-10" class="headerlink" title="Implementation"></a>Implementation</h3><p>Alarm（闹钟）、CoffeePot（咖啡壶）、Calendar（日历）、Sprinkler（喷头）是一组相关的对象，在某个对象的事件产生时需要去操作其它对象，形成了下面这种依赖结构：</p>
<div align="center"> <img src= "" data-lazy-src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/82cfda3b-b53b-4c89-9fdb-26dd2db0cd02.jpg"/> </div><br>

<p>使用中介者模式可以将复杂的依赖结构变成星形结构：</p>
<div align="center"> <img src= "" data-lazy-src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/5359cbf5-5a79-4874-9b17-f23c53c2cb80.jpg"/> </div><br>

<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">abstract</span> <span class="class"><span class="keyword">class</span> <span class="title">Colleague</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">abstract</span> <span class="keyword">void</span> <span class="title">onEvent</span><span class="params">(Mediator mediator)</span></span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Alarm</span> <span class="keyword">extends</span> <span class="title">Colleague</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onEvent</span><span class="params">(Mediator mediator)</span> </span>&#123;</span><br><span class="line">        mediator.doEvent(<span class="string">&quot;alarm&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">doAlarm</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;doAlarm()&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">CoffeePot</span> <span class="keyword">extends</span> <span class="title">Colleague</span> </span>&#123;</span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onEvent</span><span class="params">(Mediator mediator)</span> </span>&#123;</span><br><span class="line">        mediator.doEvent(<span class="string">&quot;coffeePot&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">doCoffeePot</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;doCoffeePot()&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Calender</span> <span class="keyword">extends</span> <span class="title">Colleague</span> </span>&#123;</span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onEvent</span><span class="params">(Mediator mediator)</span> </span>&#123;</span><br><span class="line">        mediator.doEvent(<span class="string">&quot;calender&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">doCalender</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;doCalender()&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Sprinkler</span> <span class="keyword">extends</span> <span class="title">Colleague</span> </span>&#123;</span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onEvent</span><span class="params">(Mediator mediator)</span> </span>&#123;</span><br><span class="line">        mediator.doEvent(<span class="string">&quot;sprinkler&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">doSprinkler</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;doSprinkler()&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">abstract</span> <span class="class"><span class="keyword">class</span> <span class="title">Mediator</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">abstract</span> <span class="keyword">void</span> <span class="title">doEvent</span><span class="params">(String eventType)</span></span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">ConcreteMediator</span> <span class="keyword">extends</span> <span class="title">Mediator</span> </span>&#123;</span><br><span class="line">    <span class="keyword">private</span> Alarm alarm;</span><br><span class="line">    <span class="keyword">private</span> CoffeePot coffeePot;</span><br><span class="line">    <span class="keyword">private</span> Calender calender;</span><br><span class="line">    <span class="keyword">private</span> Sprinkler sprinkler;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="title">ConcreteMediator</span><span class="params">(Alarm alarm, CoffeePot coffeePot, Calender calender, Sprinkler sprinkler)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">this</span>.alarm = alarm;</span><br><span class="line">        <span class="keyword">this</span>.coffeePot = coffeePot;</span><br><span class="line">        <span class="keyword">this</span>.calender = calender;</span><br><span class="line">        <span class="keyword">this</span>.sprinkler = sprinkler;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">doEvent</span><span class="params">(String eventType)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">switch</span> (eventType) &#123;</span><br><span class="line">            <span class="keyword">case</span> <span class="string">&quot;alarm&quot;</span>:</span><br><span class="line">                doAlarmEvent();</span><br><span class="line">                <span class="keyword">break</span>;</span><br><span class="line">            <span class="keyword">case</span> <span class="string">&quot;coffeePot&quot;</span>:</span><br><span class="line">                doCoffeePotEvent();</span><br><span class="line">                <span class="keyword">break</span>;</span><br><span class="line">            <span class="keyword">case</span> <span class="string">&quot;calender&quot;</span>:</span><br><span class="line">                doCalenderEvent();</span><br><span class="line">                <span class="keyword">break</span>;</span><br><span class="line">            <span class="keyword">default</span>:</span><br><span class="line">                doSprinklerEvent();</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">doAlarmEvent</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        alarm.doAlarm();</span><br><span class="line">        coffeePot.doCoffeePot();</span><br><span class="line">        calender.doCalender();</span><br><span class="line">        sprinkler.doSprinkler();</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">doCoffeePotEvent</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="comment">// ...</span></span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">doCalenderEvent</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="comment">// ...</span></span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">doSprinklerEvent</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="comment">// ...</span></span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Client</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">        Alarm alarm = <span class="keyword">new</span> Alarm();</span><br><span class="line">        CoffeePot coffeePot = <span class="keyword">new</span> CoffeePot();</span><br><span class="line">        Calender calender = <span class="keyword">new</span> Calender();</span><br><span class="line">        Sprinkler sprinkler = <span class="keyword">new</span> Sprinkler();</span><br><span class="line">        Mediator mediator = <span class="keyword">new</span> ConcreteMediator(alarm, coffeePot, calender, sprinkler);</span><br><span class="line">        <span class="comment">// 闹钟事件到达，调用中介者就可以操作相关对象</span></span><br><span class="line">        alarm.onEvent(mediator);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">doAlarm()</span><br><span class="line">doCoffeePot()</span><br><span class="line">doCalender()</span><br><span class="line">doSprinkler()</span><br></pre></td></tr></table></figure>

<h3 id="JDK-9"><a href="#JDK-9" class="headerlink" title="JDK"></a>JDK</h3><ul>
<li>All scheduleXXX() methods of <a target="_blank" rel="noopener" href="http://docs.oracle.com/javase/8/docs/api/java/util/Timer.html">java.util.Timer</a></li>
<li><a target="_blank" rel="noopener" href="http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/Executor.html#execute-java.lang.Runnable-">java.util.concurrent.Executor#execute()</a></li>
<li>submit() and invokeXXX() methods of <a target="_blank" rel="noopener" href="http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ExecutorService.html">java.util.concurrent.ExecutorService</a></li>
<li>scheduleXXX() methods of <a target="_blank" rel="noopener" href="http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ScheduledExecutorService.html">java.util.concurrent.ScheduledExecutorService</a></li>
<li><a target="_blank" rel="noopener" href="http://docs.oracle.com/javase/8/docs/api/java/lang/reflect/Method.html#invoke-java.lang.Object-java.lang.Object...-">java.lang.reflect.Method#invoke()</a></li>
</ul>
<h2 id="6-备忘录（Memento）"><a href="#6-备忘录（Memento）" class="headerlink" title="6. 备忘录（Memento）"></a>6. 备忘录（Memento）</h2><h3 id="Intent-11"><a href="#Intent-11" class="headerlink" title="Intent"></a>Intent</h3><p>在不违反封装的情况下获得对象的内部状态，从而在需要时可以将对象恢复到最初状态。</p>
<h3 id="Class-Diagram-11"><a href="#Class-Diagram-11" class="headerlink" title="Class Diagram"></a>Class Diagram</h3><ul>
<li>Originator：原始对象</li>
<li>Caretaker：负责保存好备忘录</li>
<li>Menento：备忘录，存储原始对象的的状态。备忘录实际上有两个接口，一个是提供给 Caretaker 的窄接口：它只能将备忘录传递给其它对象；一个是提供给 Originator 的宽接口，允许它访问到先前状态所需的所有数据。理想情况是只允许 Originator 访问本备忘录的内部状态。</li>
</ul>
<div align="center"> <img src= "" data-lazy-src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/50678f34-694f-45a4-91c6-34d985c83fee.png"/> </div><br>

<h3 id="Implementation-11"><a href="#Implementation-11" class="headerlink" title="Implementation"></a>Implementation</h3><p>以下实现了一个简单计算器程序，可以输入两个值，然后计算这两个值的和。备忘录模式允许将这两个值存储起来，然后在某个时刻用存储的状态进行恢复。</p>
<p>实现参考：<a target="_blank" rel="noopener" href="https://www.oodesign.com/memento-pattern-calculator-example-java-sourcecode.html">Memento Pattern - Calculator Example - Java Sourcecode</a></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Originator Interface</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">interface</span> <span class="title">Calculator</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// Create Memento</span></span><br><span class="line">    <span class="function">PreviousCalculationToCareTaker <span class="title">backupLastCalculation</span><span class="params">()</span></span>;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// setMemento</span></span><br><span class="line">    <span class="function"><span class="keyword">void</span> <span class="title">restorePreviousCalculation</span><span class="params">(PreviousCalculationToCareTaker memento)</span></span>;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">int</span> <span class="title">getCalculationResult</span><span class="params">()</span></span>;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">void</span> <span class="title">setFirstNumber</span><span class="params">(<span class="keyword">int</span> firstNumber)</span></span>;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">void</span> <span class="title">setSecondNumber</span><span class="params">(<span class="keyword">int</span> secondNumber)</span></span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Originator Implementation</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">CalculatorImp</span> <span class="keyword">implements</span> <span class="title">Calculator</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">int</span> firstNumber;</span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">int</span> secondNumber;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> PreviousCalculationToCareTaker <span class="title">backupLastCalculation</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="comment">// create a memento object used for restoring two numbers</span></span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">new</span> PreviousCalculationImp(firstNumber, secondNumber);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">restorePreviousCalculation</span><span class="params">(PreviousCalculationToCareTaker memento)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">this</span>.firstNumber = ((PreviousCalculationToOriginator) memento).getFirstNumber();</span><br><span class="line">        <span class="keyword">this</span>.secondNumber = ((PreviousCalculationToOriginator) memento).getSecondNumber();</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">getCalculationResult</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="comment">// result is adding two numbers</span></span><br><span class="line">        <span class="keyword">return</span> firstNumber + secondNumber;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">setFirstNumber</span><span class="params">(<span class="keyword">int</span> firstNumber)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">this</span>.firstNumber = firstNumber;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">setSecondNumber</span><span class="params">(<span class="keyword">int</span> secondNumber)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">this</span>.secondNumber = secondNumber;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Memento Interface to Originator</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> * This interface allows the originator to restore its state</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">interface</span> <span class="title">PreviousCalculationToOriginator</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">int</span> <span class="title">getFirstNumber</span><span class="params">()</span></span>;</span><br><span class="line">    <span class="function"><span class="keyword">int</span> <span class="title">getSecondNumber</span><span class="params">()</span></span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> *  Memento interface to CalculatorOperator (Caretaker)</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">interface</span> <span class="title">PreviousCalculationToCareTaker</span> </span>&#123;</span><br><span class="line">    <span class="comment">// no operations permitted for the caretaker</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Memento Object Implementation</span></span><br><span class="line"><span class="comment"> * &lt;p&gt;</span></span><br><span class="line"><span class="comment"> * Note that this object implements both interfaces to Originator and CareTaker</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">PreviousCalculationImp</span> <span class="keyword">implements</span> <span class="title">PreviousCalculationToCareTaker</span>,</span></span><br><span class="line"><span class="class">        <span class="title">PreviousCalculationToOriginator</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">int</span> firstNumber;</span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">int</span> secondNumber;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="title">PreviousCalculationImp</span><span class="params">(<span class="keyword">int</span> firstNumber, <span class="keyword">int</span> secondNumber)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">this</span>.firstNumber = firstNumber;</span><br><span class="line">        <span class="keyword">this</span>.secondNumber = secondNumber;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">getFirstNumber</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> firstNumber;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">getSecondNumber</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> secondNumber;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * CareTaker object</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Client</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">        <span class="comment">// program starts</span></span><br><span class="line">        Calculator calculator = <span class="keyword">new</span> CalculatorImp();</span><br><span class="line"></span><br><span class="line">        <span class="comment">// assume user enters two numbers</span></span><br><span class="line">        calculator.setFirstNumber(<span class="number">10</span>);</span><br><span class="line">        calculator.setSecondNumber(<span class="number">100</span>);</span><br><span class="line"></span><br><span class="line">        <span class="comment">// find result</span></span><br><span class="line">        System.out.println(calculator.getCalculationResult());</span><br><span class="line"></span><br><span class="line">        <span class="comment">// Store result of this calculation in case of error</span></span><br><span class="line">        PreviousCalculationToCareTaker memento = calculator.backupLastCalculation();</span><br><span class="line"></span><br><span class="line">        <span class="comment">// user enters a number</span></span><br><span class="line">        calculator.setFirstNumber(<span class="number">17</span>);</span><br><span class="line"></span><br><span class="line">        <span class="comment">// user enters a wrong second number and calculates result</span></span><br><span class="line">        calculator.setSecondNumber(-<span class="number">290</span>);</span><br><span class="line"></span><br><span class="line">        <span class="comment">// calculate result</span></span><br><span class="line">        System.out.println(calculator.getCalculationResult());</span><br><span class="line"></span><br><span class="line">        <span class="comment">// user hits CTRL + Z to undo last operation and see last result</span></span><br><span class="line">        calculator.restorePreviousCalculation(memento);</span><br><span class="line"></span><br><span class="line">        <span class="comment">// result restored</span></span><br><span class="line">        System.out.println(calculator.getCalculationResult());</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight html"><table><tr><td class="code"><pre><span class="line">110</span><br><span class="line">-273</span><br><span class="line">110</span><br></pre></td></tr></table></figure>

<h3 id="JDK-10"><a href="#JDK-10" class="headerlink" title="JDK"></a>JDK</h3><ul>
<li>java.io.Serializable</li>
</ul>
<h2 id="7-观察者（Observer）"><a href="#7-观察者（Observer）" class="headerlink" title="7. 观察者（Observer）"></a>7. 观察者（Observer）</h2><h3 id="Intent-12"><a href="#Intent-12" class="headerlink" title="Intent"></a>Intent</h3><p>定义对象之间的一对多依赖，当一个对象状态改变时，它的所有依赖都会收到通知并且自动更新状态。</p>
<p>主题（Subject）是被观察的对象，而其所有依赖者（Observer）称为观察者。</p>
<div align="center"> <img src= "" data-lazy-src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/7a3c6a30-c735-4edb-8115-337288a4f0f2.jpg" width="600"/> </div><br>

<h3 id="Class-Diagram-12"><a href="#Class-Diagram-12" class="headerlink" title="Class Diagram"></a>Class Diagram</h3><p>主题（Subject）具有注册和移除观察者、并通知所有观察者的功能，主题是通过维护一张观察者列表来实现这些操作的。</p>
<p>观察者（Observer）的注册功能需要调用主题的 registerObserver() 方法。</p>
<div align="center"> <img src= "" data-lazy-src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/a8c8f894-a712-447c-9906-5caef6a016e3.png"/> </div><br>

<h3 id="Implementation-12"><a href="#Implementation-12" class="headerlink" title="Implementation"></a>Implementation</h3><p>天气数据布告板会在天气信息发生改变时更新其内容，布告板有多个，并且在将来会继续增加。</p>
<div align="center"> <img src= "" data-lazy-src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/b1df9732-86ce-4d69-9f06-fba1db7b3b5a.jpg"/> </div><br>

<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">interface</span> <span class="title">Subject</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">void</span> <span class="title">registerObserver</span><span class="params">(Observer o)</span></span>;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">void</span> <span class="title">removeObserver</span><span class="params">(Observer o)</span></span>;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">void</span> <span class="title">notifyObserver</span><span class="params">()</span></span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">WeatherData</span> <span class="keyword">implements</span> <span class="title">Subject</span> </span>&#123;</span><br><span class="line">    <span class="keyword">private</span> List&lt;Observer&gt; observers;</span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">float</span> temperature;</span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">float</span> humidity;</span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">float</span> pressure;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="title">WeatherData</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        observers = <span class="keyword">new</span> ArrayList&lt;&gt;();</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">setMeasurements</span><span class="params">(<span class="keyword">float</span> temperature, <span class="keyword">float</span> humidity, <span class="keyword">float</span> pressure)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">this</span>.temperature = temperature;</span><br><span class="line">        <span class="keyword">this</span>.humidity = humidity;</span><br><span class="line">        <span class="keyword">this</span>.pressure = pressure;</span><br><span class="line">        notifyObserver();</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">registerObserver</span><span class="params">(Observer o)</span> </span>&#123;</span><br><span class="line">        observers.add(o);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">removeObserver</span><span class="params">(Observer o)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">int</span> i = observers.indexOf(o);</span><br><span class="line">        <span class="keyword">if</span> (i &gt;= <span class="number">0</span>) &#123;</span><br><span class="line">            observers.remove(i);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">notifyObserver</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">for</span> (Observer o : observers) &#123;</span><br><span class="line">            o.update(temperature, humidity, pressure);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">interface</span> <span class="title">Observer</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">void</span> <span class="title">update</span><span class="params">(<span class="keyword">float</span> temp, <span class="keyword">float</span> humidity, <span class="keyword">float</span> pressure)</span></span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">StatisticsDisplay</span> <span class="keyword">implements</span> <span class="title">Observer</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="title">StatisticsDisplay</span><span class="params">(Subject weatherData)</span> </span>&#123;</span><br><span class="line">        weatherData.reisterObserver(<span class="keyword">this</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">update</span><span class="params">(<span class="keyword">float</span> temp, <span class="keyword">float</span> humidity, <span class="keyword">float</span> pressure)</span> </span>&#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;StatisticsDisplay.update: &quot;</span> + temp + <span class="string">&quot; &quot;</span> + humidity + <span class="string">&quot; &quot;</span> + pressure);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">CurrentConditionsDisplay</span> <span class="keyword">implements</span> <span class="title">Observer</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="title">CurrentConditionsDisplay</span><span class="params">(Subject weatherData)</span> </span>&#123;</span><br><span class="line">        weatherData.registerObserver(<span class="keyword">this</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">update</span><span class="params">(<span class="keyword">float</span> temp, <span class="keyword">float</span> humidity, <span class="keyword">float</span> pressure)</span> </span>&#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;CurrentConditionsDisplay.update: &quot;</span> + temp + <span class="string">&quot; &quot;</span> + humidity + <span class="string">&quot; &quot;</span> + pressure);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">WeatherStation</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">        WeatherData weatherData = <span class="keyword">new</span> WeatherData();</span><br><span class="line">        CurrentConditionsDisplay currentConditionsDisplay = <span class="keyword">new</span> CurrentConditionsDisplay(weatherData);</span><br><span class="line">        StatisticsDisplay statisticsDisplay = <span class="keyword">new</span> StatisticsDisplay(weatherData);</span><br><span class="line"></span><br><span class="line">        weatherData.setMeasurements(<span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>);</span><br><span class="line">        weatherData.setMeasurements(<span class="number">1</span>, <span class="number">1</span>, <span class="number">1</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight html"><table><tr><td class="code"><pre><span class="line">CurrentConditionsDisplay.update: 0.0 0.0 0.0</span><br><span class="line">StatisticsDisplay.update: 0.0 0.0 0.0</span><br><span class="line">CurrentConditionsDisplay.update: 1.0 1.0 1.0</span><br><span class="line">StatisticsDisplay.update: 1.0 1.0 1.0</span><br></pre></td></tr></table></figure>

<h3 id="JDK-11"><a href="#JDK-11" class="headerlink" title="JDK"></a>JDK</h3><ul>
<li><a target="_blank" rel="noopener" href="http://docs.oracle.com/javase/8/docs/api/java/util/Observer.html">java.util.Observer</a></li>
<li><a target="_blank" rel="noopener" href="http://docs.oracle.com/javase/8/docs/api/java/util/EventListener.html">java.util.EventListener</a></li>
<li><a target="_blank" rel="noopener" href="http://docs.oracle.com/javaee/7/api/javax/servlet/http/HttpSessionBindingListener.html">javax.servlet.http.HttpSessionBindingListener</a></li>
<li><a target="_blank" rel="noopener" href="https://github.com/ReactiveX/RxJava">RxJava</a></li>
</ul>
<h2 id="8-状态（State）"><a href="#8-状态（State）" class="headerlink" title="8. 状态（State）"></a>8. 状态（State）</h2><h3 id="Intent-13"><a href="#Intent-13" class="headerlink" title="Intent"></a>Intent</h3><p>允许对象在内部状态改变时改变它的行为，对象看起来好像修改了它所属的类。</p>
<h3 id="Class-Diagram-13"><a href="#Class-Diagram-13" class="headerlink" title="Class Diagram"></a>Class Diagram</h3><div align="center"> <img src= "" data-lazy-src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/79df886f-fdc3-4020-a07f-c991bb58e0d8.png"/> </div><br>

<h3 id="Implementation-13"><a href="#Implementation-13" class="headerlink" title="Implementation"></a>Implementation</h3><p>糖果销售机有多种状态，每种状态下销售机有不同的行为，状态可以发生转移，使得销售机的行为也发生改变。</p>
<div align="center"> <img src= "" data-lazy-src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/396be981-3f2c-4fd9-8101-dbf9c841504b.jpg" width="600"/> </div><br>

<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">interface</span> <span class="title">State</span> </span>&#123;</span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 投入 25 分钱</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="function"><span class="keyword">void</span> <span class="title">insertQuarter</span><span class="params">()</span></span>;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 退回 25 分钱</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="function"><span class="keyword">void</span> <span class="title">ejectQuarter</span><span class="params">()</span></span>;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 转动曲柄</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="function"><span class="keyword">void</span> <span class="title">turnCrank</span><span class="params">()</span></span>;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 发放糖果</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="function"><span class="keyword">void</span> <span class="title">dispense</span><span class="params">()</span></span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">HasQuarterState</span> <span class="keyword">implements</span> <span class="title">State</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">private</span> GumballMachine gumballMachine;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="title">HasQuarterState</span><span class="params">(GumballMachine gumballMachine)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">this</span>.gumballMachine = gumballMachine;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">insertQuarter</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;You can&#x27;t insert another quarter&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">ejectQuarter</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;Quarter returned&quot;</span>);</span><br><span class="line">        gumballMachine.setState(gumballMachine.getNoQuarterState());</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">turnCrank</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;You turned...&quot;</span>);</span><br><span class="line">        gumballMachine.setState(gumballMachine.getSoldState());</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">dispense</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;No gumball dispensed&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">NoQuarterState</span> <span class="keyword">implements</span> <span class="title">State</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    GumballMachine gumballMachine;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="title">NoQuarterState</span><span class="params">(GumballMachine gumballMachine)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">this</span>.gumballMachine = gumballMachine;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">insertQuarter</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;You insert a quarter&quot;</span>);</span><br><span class="line">        gumballMachine.setState(gumballMachine.getHasQuarterState());</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">ejectQuarter</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;You haven&#x27;t insert a quarter&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">turnCrank</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;You turned, but there&#x27;s no quarter&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">dispense</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;You need to pay first&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">SoldOutState</span> <span class="keyword">implements</span> <span class="title">State</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    GumballMachine gumballMachine;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="title">SoldOutState</span><span class="params">(GumballMachine gumballMachine)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">this</span>.gumballMachine = gumballMachine;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">insertQuarter</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;You can&#x27;t insert a quarter, the machine is sold out&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">ejectQuarter</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;You can&#x27;t eject, you haven&#x27;t inserted a quarter yet&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">turnCrank</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;You turned, but there are no gumballs&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">dispense</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;No gumball dispensed&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">SoldState</span> <span class="keyword">implements</span> <span class="title">State</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    GumballMachine gumballMachine;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="title">SoldState</span><span class="params">(GumballMachine gumballMachine)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">this</span>.gumballMachine = gumballMachine;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">insertQuarter</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;Please wait, we&#x27;re already giving you a gumball&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">ejectQuarter</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;Sorry, you already turned the crank&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">turnCrank</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;Turning twice doesn&#x27;t get you another gumball!&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">dispense</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        gumballMachine.releaseBall();</span><br><span class="line">        <span class="keyword">if</span> (gumballMachine.getCount() &gt; <span class="number">0</span>) &#123;</span><br><span class="line">            gumballMachine.setState(gumballMachine.getNoQuarterState());</span><br><span class="line">        &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">            System.out.println(<span class="string">&quot;Oops, out of gumballs&quot;</span>);</span><br><span class="line">            gumballMachine.setState(gumballMachine.getSoldOutState());</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">GumballMachine</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">private</span> State soldOutState;</span><br><span class="line">    <span class="keyword">private</span> State noQuarterState;</span><br><span class="line">    <span class="keyword">private</span> State hasQuarterState;</span><br><span class="line">    <span class="keyword">private</span> State soldState;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">private</span> State state;</span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">int</span> count = <span class="number">0</span>;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="title">GumballMachine</span><span class="params">(<span class="keyword">int</span> numberGumballs)</span> </span>&#123;</span><br><span class="line">        count = numberGumballs;</span><br><span class="line">        soldOutState = <span class="keyword">new</span> SoldOutState(<span class="keyword">this</span>);</span><br><span class="line">        noQuarterState = <span class="keyword">new</span> NoQuarterState(<span class="keyword">this</span>);</span><br><span class="line">        hasQuarterState = <span class="keyword">new</span> HasQuarterState(<span class="keyword">this</span>);</span><br><span class="line">        soldState = <span class="keyword">new</span> SoldState(<span class="keyword">this</span>);</span><br><span class="line"></span><br><span class="line">        <span class="keyword">if</span> (numberGumballs &gt; <span class="number">0</span>) &#123;</span><br><span class="line">            state = noQuarterState;</span><br><span class="line">        &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">            state = soldOutState;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">insertQuarter</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        state.insertQuarter();</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">ejectQuarter</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        state.ejectQuarter();</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">turnCrank</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        state.turnCrank();</span><br><span class="line">        state.dispense();</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">setState</span><span class="params">(State state)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">this</span>.state = state;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">releaseBall</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;A gumball comes rolling out the slot...&quot;</span>);</span><br><span class="line">        <span class="keyword">if</span> (count != <span class="number">0</span>) &#123;</span><br><span class="line">            count -= <span class="number">1</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> State <span class="title">getSoldOutState</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> soldOutState;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> State <span class="title">getNoQuarterState</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> noQuarterState;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> State <span class="title">getHasQuarterState</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> hasQuarterState;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> State <span class="title">getSoldState</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> soldState;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">getCount</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> count;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Client</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">        GumballMachine gumballMachine = <span class="keyword">new</span> GumballMachine(<span class="number">5</span>);</span><br><span class="line"></span><br><span class="line">        gumballMachine.insertQuarter();</span><br><span class="line">        gumballMachine.turnCrank();</span><br><span class="line"></span><br><span class="line">        gumballMachine.insertQuarter();</span><br><span class="line">        gumballMachine.ejectQuarter();</span><br><span class="line">        gumballMachine.turnCrank();</span><br><span class="line"></span><br><span class="line">        gumballMachine.insertQuarter();</span><br><span class="line">        gumballMachine.turnCrank();</span><br><span class="line">        gumballMachine.insertQuarter();</span><br><span class="line">        gumballMachine.turnCrank();</span><br><span class="line">        gumballMachine.ejectQuarter();</span><br><span class="line"></span><br><span class="line">        gumballMachine.insertQuarter();</span><br><span class="line">        gumballMachine.insertQuarter();</span><br><span class="line">        gumballMachine.turnCrank();</span><br><span class="line">        gumballMachine.insertQuarter();</span><br><span class="line">        gumballMachine.turnCrank();</span><br><span class="line">        gumballMachine.insertQuarter();</span><br><span class="line">        gumballMachine.turnCrank();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight html"><table><tr><td class="code"><pre><span class="line">You insert a quarter</span><br><span class="line">You turned...</span><br><span class="line">A gumball comes rolling out the slot...</span><br><span class="line">You insert a quarter</span><br><span class="line">Quarter returned</span><br><span class="line">You turned, but there&#x27;s no quarter</span><br><span class="line">You need to pay first</span><br><span class="line">You insert a quarter</span><br><span class="line">You turned...</span><br><span class="line">A gumball comes rolling out the slot...</span><br><span class="line">You insert a quarter</span><br><span class="line">You turned...</span><br><span class="line">A gumball comes rolling out the slot...</span><br><span class="line">You haven&#x27;t insert a quarter</span><br><span class="line">You insert a quarter</span><br><span class="line">You can&#x27;t insert another quarter</span><br><span class="line">You turned...</span><br><span class="line">A gumball comes rolling out the slot...</span><br><span class="line">You insert a quarter</span><br><span class="line">You turned...</span><br><span class="line">A gumball comes rolling out the slot...</span><br><span class="line">Oops, out of gumballs</span><br><span class="line">You can&#x27;t insert a quarter, the machine is sold out</span><br><span class="line">You turned, but there are no gumballs</span><br><span class="line">No gumball dispensed</span><br></pre></td></tr></table></figure>

<h2 id="9-策略（Strategy）"><a href="#9-策略（Strategy）" class="headerlink" title="9. 策略（Strategy）"></a>9. 策略（Strategy）</h2><h3 id="Intent-14"><a href="#Intent-14" class="headerlink" title="Intent"></a>Intent</h3><p>定义一系列算法，封装每个算法，并使它们可以互换。</p>
<p>策略模式可以让算法独立于使用它的客户端。</p>
<h3 id="Class-Diagram-14"><a href="#Class-Diagram-14" class="headerlink" title="Class Diagram"></a>Class Diagram</h3><ul>
<li>Strategy 接口定义了一个算法族，它们都实现了  behavior() 方法。</li>
<li>Context 是使用到该算法族的类，其中的 doSomething() 方法会调用 behavior()，setStrategy(Strategy) 方法可以动态地改变 strategy 对象，也就是说能动态地改变 Context 所使用的算法。</li>
</ul>
<div align="center"> <img src= "" data-lazy-src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/cd1be8c2-755a-4a66-ad92-2e30f8f47922.png"/> </div><br>

<h3 id="与状态模式的比较"><a href="#与状态模式的比较" class="headerlink" title="与状态模式的比较"></a>与状态模式的比较</h3><p>状态模式的类图和策略模式类似，并且都是能够动态改变对象的行为。但是状态模式是通过状态转移来改变 Context 所组合的 State 对象，而策略模式是通过 Context 本身的决策来改变组合的 Strategy 对象。所谓的状态转移，是指 Context 在运行过程中由于一些条件发生改变而使得 State 对象发生改变，注意必须要是在运行过程中。</p>
<p>状态模式主要是用来解决状态转移的问题，当状态发生转移了，那么 Context 对象就会改变它的行为；而策略模式主要是用来封装一组可以互相替代的算法族，并且可以根据需要动态地去替换 Context 使用的算法。</p>
<h3 id="Implementation-14"><a href="#Implementation-14" class="headerlink" title="Implementation"></a>Implementation</h3><p>设计一个鸭子，它可以动态地改变叫声。这里的算法族是鸭子的叫声行为。</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">interface</span> <span class="title">QuackBehavior</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">void</span> <span class="title">quack</span><span class="params">()</span></span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Quack</span> <span class="keyword">implements</span> <span class="title">QuackBehavior</span> </span>&#123;</span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">quack</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;quack!&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Squeak</span> <span class="keyword">implements</span> <span class="title">QuackBehavior</span></span>&#123;</span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">quack</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;squeak!&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Duck</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">private</span> QuackBehavior quackBehavior;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">performQuack</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">if</span> (quackBehavior != <span class="keyword">null</span>) &#123;</span><br><span class="line">            quackBehavior.quack();</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">setQuackBehavior</span><span class="params">(QuackBehavior quackBehavior)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">this</span>.quackBehavior = quackBehavior;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Client</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">        Duck duck = <span class="keyword">new</span> Duck();</span><br><span class="line">        duck.setQuackBehavior(<span class="keyword">new</span> Squeak());</span><br><span class="line">        duck.performQuack();</span><br><span class="line">        duck.setQuackBehavior(<span class="keyword">new</span> Quack());</span><br><span class="line">        duck.performQuack();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight html"><table><tr><td class="code"><pre><span class="line">squeak!</span><br><span class="line">quack!</span><br></pre></td></tr></table></figure>

<h3 id="JDK-12"><a href="#JDK-12" class="headerlink" title="JDK"></a>JDK</h3><ul>
<li>java.util.Comparator#compare()</li>
<li>javax.servlet.http.HttpServlet</li>
<li>javax.servlet.Filter#doFilter()</li>
</ul>
<h2 id="10-模板方法（Template-Method）"><a href="#10-模板方法（Template-Method）" class="headerlink" title="10. 模板方法（Template Method）"></a>10. 模板方法（Template Method）</h2><h3 id="Intent-15"><a href="#Intent-15" class="headerlink" title="Intent"></a>Intent</h3><p>定义算法框架，并将一些步骤的实现延迟到子类。</p>
<p>通过模板方法，子类可以重新定义算法的某些步骤，而不用改变算法的结构。</p>
<h3 id="Class-Diagram-15"><a href="#Class-Diagram-15" class="headerlink" title="Class Diagram"></a>Class Diagram</h3><div align="center"> <img src= "" data-lazy-src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/ac6a794b-68c0-486c-902f-8d988eee5766.png"/> </div><br>

<h3 id="Implementation-15"><a href="#Implementation-15" class="headerlink" title="Implementation"></a>Implementation</h3><p>冲咖啡和冲茶都有类似的流程，但是某些步骤会有点不一样，要求复用那些相同步骤的代码。</p>
<div align="center"> <img src= "" data-lazy-src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/11236498-1417-46ce-a1b0-e10054256955.png"/> </div><br>

<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">abstract</span> <span class="class"><span class="keyword">class</span> <span class="title">CaffeineBeverage</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">final</span> <span class="keyword">void</span> <span class="title">prepareRecipe</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        boilWater();</span><br><span class="line">        brew();</span><br><span class="line">        pourInCup();</span><br><span class="line">        addCondiments();</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">abstract</span> <span class="keyword">void</span> <span class="title">brew</span><span class="params">()</span></span>;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">abstract</span> <span class="keyword">void</span> <span class="title">addCondiments</span><span class="params">()</span></span>;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">void</span> <span class="title">boilWater</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;boilWater&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">void</span> <span class="title">pourInCup</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;pourInCup&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Coffee</span> <span class="keyword">extends</span> <span class="title">CaffeineBeverage</span> </span>&#123;</span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">void</span> <span class="title">brew</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;Coffee.brew&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">void</span> <span class="title">addCondiments</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;Coffee.addCondiments&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Tea</span> <span class="keyword">extends</span> <span class="title">CaffeineBeverage</span> </span>&#123;</span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">void</span> <span class="title">brew</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;Tea.brew&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">void</span> <span class="title">addCondiments</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;Tea.addCondiments&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Client</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">        CaffeineBeverage caffeineBeverage = <span class="keyword">new</span> Coffee();</span><br><span class="line">        caffeineBeverage.prepareRecipe();</span><br><span class="line">        System.out.println(<span class="string">&quot;-----------&quot;</span>);</span><br><span class="line">        caffeineBeverage = <span class="keyword">new</span> Tea();</span><br><span class="line">        caffeineBeverage.prepareRecipe();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight html"><table><tr><td class="code"><pre><span class="line">boilWater</span><br><span class="line">Coffee.brew</span><br><span class="line">pourInCup</span><br><span class="line">Coffee.addCondiments</span><br><span class="line">-----------</span><br><span class="line">boilWater</span><br><span class="line">Tea.brew</span><br><span class="line">pourInCup</span><br><span class="line">Tea.addCondiments</span><br></pre></td></tr></table></figure>

<h3 id="JDK-13"><a href="#JDK-13" class="headerlink" title="JDK"></a>JDK</h3><ul>
<li>java.util.Collections#sort()</li>
<li>java.io.InputStream#skip()</li>
<li>java.io.InputStream#read()</li>
<li>java.util.AbstractList#indexOf()</li>
</ul>
<h2 id="11-访问者（Visitor）"><a href="#11-访问者（Visitor）" class="headerlink" title="11. 访问者（Visitor）"></a>11. 访问者（Visitor）</h2><h3 id="Intent-16"><a href="#Intent-16" class="headerlink" title="Intent"></a>Intent</h3><p>为一个对象结构（比如组合结构）增加新能力。</p>
<h3 id="Class-Diagram-16"><a href="#Class-Diagram-16" class="headerlink" title="Class Diagram"></a>Class Diagram</h3><ul>
<li>Visitor：访问者，为每一个 ConcreteElement 声明一个 visit 操作</li>
<li>ConcreteVisitor：具体访问者，存储遍历过程中的累计结果</li>
<li>ObjectStructure：对象结构，可以是组合结构，或者是一个集合。</li>
</ul>
<div align="center"> <img src= "" data-lazy-src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/79c6f036-bde6-4393-85a3-ef36a0327bd2.png"/> </div><br>

<h3 id="Implementation-16"><a href="#Implementation-16" class="headerlink" title="Implementation"></a>Implementation</h3><figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">interface</span> <span class="title">Element</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">void</span> <span class="title">accept</span><span class="params">(Visitor visitor)</span></span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">CustomerGroup</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">private</span> List&lt;Customer&gt; customers = <span class="keyword">new</span> ArrayList&lt;&gt;();</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">void</span> <span class="title">accept</span><span class="params">(Visitor visitor)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">for</span> (Customer customer : customers) &#123;</span><br><span class="line">            customer.accept(visitor);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">void</span> <span class="title">addCustomer</span><span class="params">(Customer customer)</span> </span>&#123;</span><br><span class="line">        customers.add(customer);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Customer</span> <span class="keyword">implements</span> <span class="title">Element</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">private</span> String name;</span><br><span class="line">    <span class="keyword">private</span> List&lt;Order&gt; orders = <span class="keyword">new</span> ArrayList&lt;&gt;();</span><br><span class="line"></span><br><span class="line">    Customer(String name) &#123;</span><br><span class="line">        <span class="keyword">this</span>.name = name;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function">String <span class="title">getName</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> name;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">void</span> <span class="title">addOrder</span><span class="params">(Order order)</span> </span>&#123;</span><br><span class="line">        orders.add(order);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">accept</span><span class="params">(Visitor visitor)</span> </span>&#123;</span><br><span class="line">        visitor.visit(<span class="keyword">this</span>);</span><br><span class="line">        <span class="keyword">for</span> (Order order : orders) &#123;</span><br><span class="line">            order.accept(visitor);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Order</span> <span class="keyword">implements</span> <span class="title">Element</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">private</span> String name;</span><br><span class="line">    <span class="keyword">private</span> List&lt;Item&gt; items = <span class="keyword">new</span> ArrayList();</span><br><span class="line"></span><br><span class="line">    Order(String name) &#123;</span><br><span class="line">        <span class="keyword">this</span>.name = name;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    Order(String name, String itemName) &#123;</span><br><span class="line">        <span class="keyword">this</span>.name = name;</span><br><span class="line">        <span class="keyword">this</span>.addItem(<span class="keyword">new</span> Item(itemName));</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function">String <span class="title">getName</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> name;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">void</span> <span class="title">addItem</span><span class="params">(Item item)</span> </span>&#123;</span><br><span class="line">        items.add(item);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">accept</span><span class="params">(Visitor visitor)</span> </span>&#123;</span><br><span class="line">        visitor.visit(<span class="keyword">this</span>);</span><br><span class="line"></span><br><span class="line">        <span class="keyword">for</span> (Item item : items) &#123;</span><br><span class="line">            item.accept(visitor);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Item</span> <span class="keyword">implements</span> <span class="title">Element</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">private</span> String name;</span><br><span class="line"></span><br><span class="line">    Item(String name) &#123;</span><br><span class="line">        <span class="keyword">this</span>.name = name;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function">String <span class="title">getName</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> name;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">accept</span><span class="params">(Visitor visitor)</span> </span>&#123;</span><br><span class="line">        visitor.visit(<span class="keyword">this</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">interface</span> <span class="title">Visitor</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">void</span> <span class="title">visit</span><span class="params">(Customer customer)</span></span>;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">void</span> <span class="title">visit</span><span class="params">(Order order)</span></span>;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">void</span> <span class="title">visit</span><span class="params">(Item item)</span></span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">GeneralReport</span> <span class="keyword">implements</span> <span class="title">Visitor</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">int</span> customersNo;</span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">int</span> ordersNo;</span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">int</span> itemsNo;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">visit</span><span class="params">(Customer customer)</span> </span>&#123;</span><br><span class="line">        System.out.println(customer.getName());</span><br><span class="line">        customersNo++;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">visit</span><span class="params">(Order order)</span> </span>&#123;</span><br><span class="line">        System.out.println(order.getName());</span><br><span class="line">        ordersNo++;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">visit</span><span class="params">(Item item)</span> </span>&#123;</span><br><span class="line">        System.out.println(item.getName());</span><br><span class="line">        itemsNo++;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">displayResults</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;Number of customers: &quot;</span> + customersNo);</span><br><span class="line">        System.out.println(<span class="string">&quot;Number of orders:    &quot;</span> + ordersNo);</span><br><span class="line">        System.out.println(<span class="string">&quot;Number of items:     &quot;</span> + itemsNo);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Client</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">        Customer customer1 = <span class="keyword">new</span> Customer(<span class="string">&quot;customer1&quot;</span>);</span><br><span class="line">        customer1.addOrder(<span class="keyword">new</span> Order(<span class="string">&quot;order1&quot;</span>, <span class="string">&quot;item1&quot;</span>));</span><br><span class="line">        customer1.addOrder(<span class="keyword">new</span> Order(<span class="string">&quot;order2&quot;</span>, <span class="string">&quot;item1&quot;</span>));</span><br><span class="line">        customer1.addOrder(<span class="keyword">new</span> Order(<span class="string">&quot;order3&quot;</span>, <span class="string">&quot;item1&quot;</span>));</span><br><span class="line"></span><br><span class="line">        Order order = <span class="keyword">new</span> Order(<span class="string">&quot;order_a&quot;</span>);</span><br><span class="line">        order.addItem(<span class="keyword">new</span> Item(<span class="string">&quot;item_a1&quot;</span>));</span><br><span class="line">        order.addItem(<span class="keyword">new</span> Item(<span class="string">&quot;item_a2&quot;</span>));</span><br><span class="line">        order.addItem(<span class="keyword">new</span> Item(<span class="string">&quot;item_a3&quot;</span>));</span><br><span class="line">        Customer customer2 = <span class="keyword">new</span> Customer(<span class="string">&quot;customer2&quot;</span>);</span><br><span class="line">        customer2.addOrder(order);</span><br><span class="line"></span><br><span class="line">        CustomerGroup customers = <span class="keyword">new</span> CustomerGroup();</span><br><span class="line">        customers.addCustomer(customer1);</span><br><span class="line">        customers.addCustomer(customer2);</span><br><span class="line"></span><br><span class="line">        GeneralReport visitor = <span class="keyword">new</span> GeneralReport();</span><br><span class="line">        customers.accept(visitor);</span><br><span class="line">        visitor.displayResults();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight html"><table><tr><td class="code"><pre><span class="line">customer1</span><br><span class="line">order1</span><br><span class="line">item1</span><br><span class="line">order2</span><br><span class="line">item1</span><br><span class="line">order3</span><br><span class="line">item1</span><br><span class="line">customer2</span><br><span class="line">order_a</span><br><span class="line">item_a1</span><br><span class="line">item_a2</span><br><span class="line">item_a3</span><br><span class="line">Number of customers: 2</span><br><span class="line">Number of orders:    4</span><br><span class="line">Number of items:     6</span><br></pre></td></tr></table></figure>

<h3 id="JDK-14"><a href="#JDK-14" class="headerlink" title="JDK"></a>JDK</h3><ul>
<li>javax.lang.model.element.Element and javax.lang.model.element.ElementVisitor</li>
<li>javax.lang.model.type.TypeMirror and javax.lang.model.type.TypeVisitor</li>
</ul>
<h2 id="12-空对象（Null）"><a href="#12-空对象（Null）" class="headerlink" title="12. 空对象（Null）"></a>12. 空对象（Null）</h2><h3 id="Intent-17"><a href="#Intent-17" class="headerlink" title="Intent"></a>Intent</h3><p>使用什么都不做的空对象来代替 NULL。</p>
<p>一个方法返回 NULL，意味着方法的调用端需要去检查返回值是否是 NULL，这么做会导致非常多的冗余的检查代码。并且如果某一个调用端忘记了做这个检查返回值，而直接使用返回的对象，那么就有可能抛出空指针异常。</p>
<h3 id="Class-Diagram-17"><a href="#Class-Diagram-17" class="headerlink" title="Class Diagram"></a>Class Diagram</h3><div align="center"> <img src= "" data-lazy-src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/22870bbe-898f-4c17-a31a-d7c5ee5d1c10.png"/> </div><br>

<h3 id="Implementation-17"><a href="#Implementation-17" class="headerlink" title="Implementation"></a>Implementation</h3><figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">abstract</span> <span class="class"><span class="keyword">class</span> <span class="title">AbstractOperation</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">abstract</span> <span class="keyword">void</span> <span class="title">request</span><span class="params">()</span></span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">RealOperation</span> <span class="keyword">extends</span> <span class="title">AbstractOperation</span> </span>&#123;</span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">void</span> <span class="title">request</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;do something&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">NullOperation</span> <span class="keyword">extends</span> <span class="title">AbstractOperation</span></span>&#123;</span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">void</span> <span class="title">request</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="comment">// do nothing</span></span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Client</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">        AbstractOperation abstractOperation = func(-<span class="number">1</span>);</span><br><span class="line">        abstractOperation.request();</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> AbstractOperation <span class="title">func</span><span class="params">(<span class="keyword">int</span> para)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">if</span> (para &lt; <span class="number">0</span>) &#123;</span><br><span class="line">            <span class="keyword">return</span> <span class="keyword">new</span> NullOperation();</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">new</span> RealOperation();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h1 id="四、结构型"><a href="#四、结构型" class="headerlink" title="四、结构型"></a>四、结构型</h1><h2 id="1-适配器（Adapter）"><a href="#1-适配器（Adapter）" class="headerlink" title="1. 适配器（Adapter）"></a>1. 适配器（Adapter）</h2><h3 id="Intent-18"><a href="#Intent-18" class="headerlink" title="Intent"></a>Intent</h3><p>把一个类接口转换成另一个用户需要的接口。</p>
<div align="center"> <img src= "" data-lazy-src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/3d5b828e-5c4d-48d8-a440-281e4a8e1c92.png"/> </div><br>

<h3 id="Class-Diagram-18"><a href="#Class-Diagram-18" class="headerlink" title="Class Diagram"></a>Class Diagram</h3><div align="center"> <img src= "" data-lazy-src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/ff5152fc-4ff3-44c4-95d6-1061002c364a.png"/> </div><br>

<h3 id="Implementation-18"><a href="#Implementation-18" class="headerlink" title="Implementation"></a>Implementation</h3><p>鸭子（Duck）和火鸡（Turkey）拥有不同的叫声，Duck 的叫声调用 quack() 方法，而 Turkey 调用 gobble() 方法。</p>
<p>要求将 Turkey 的 gobble() 方法适配成 Duck 的 quack() 方法，从而让火鸡冒充鸭子！</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">interface</span> <span class="title">Duck</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">void</span> <span class="title">quack</span><span class="params">()</span></span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">interface</span> <span class="title">Turkey</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">void</span> <span class="title">gobble</span><span class="params">()</span></span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">WildTurkey</span> <span class="keyword">implements</span> <span class="title">Turkey</span> </span>&#123;</span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">gobble</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;gobble!&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">TurkeyAdapter</span> <span class="keyword">implements</span> <span class="title">Duck</span> </span>&#123;</span><br><span class="line">    Turkey turkey;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="title">TurkeyAdapter</span><span class="params">(Turkey turkey)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">this</span>.turkey = turkey;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">quack</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        turkey.gobble();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Client</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">        Turkey turkey = <span class="keyword">new</span> WildTurkey();</span><br><span class="line">        Duck duck = <span class="keyword">new</span> TurkeyAdapter(turkey);</span><br><span class="line">        duck.quack();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h3 id="JDK-15"><a href="#JDK-15" class="headerlink" title="JDK"></a>JDK</h3><ul>
<li><a target="_blank" rel="noopener" href="http://docs.oracle.com/javase/8/docs/api/java/util/Arrays.html#asList%28T...%29">java.util.Arrays#asList()</a></li>
<li><a target="_blank" rel="noopener" href="https://docs.oracle.com/javase/8/docs/api/java/util/Collections.html#list-java.util.Enumeration-">java.util.Collections#list()</a></li>
<li><a target="_blank" rel="noopener" href="https://docs.oracle.com/javase/8/docs/api/java/util/Collections.html#enumeration-java.util.Collection-">java.util.Collections#enumeration()</a></li>
<li><a target="_blank" rel="noopener" href="http://docs.oracle.com/javase/8/docs/api/javax/xml/bind/annotation/adapters/XmlAdapter.html#marshal-BoundType-">javax.xml.bind.annotation.adapters.XMLAdapter</a></li>
</ul>
<h2 id="2-桥接（Bridge）"><a href="#2-桥接（Bridge）" class="headerlink" title="2. 桥接（Bridge）"></a>2. 桥接（Bridge）</h2><h3 id="Intent-19"><a href="#Intent-19" class="headerlink" title="Intent"></a>Intent</h3><p>将抽象与实现分离开来，使它们可以独立变化。</p>
<h3 id="Class-Diagram-19"><a href="#Class-Diagram-19" class="headerlink" title="Class Diagram"></a>Class Diagram</h3><ul>
<li>Abstraction：定义抽象类的接口</li>
<li>Implementor：定义实现类接口</li>
</ul>
<div align="center"> <img src= "" data-lazy-src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/2a1f8b0f-1dd7-4409-b177-a381c58066ad.png"/> </div><br>

<h3 id="Implementation-19"><a href="#Implementation-19" class="headerlink" title="Implementation"></a>Implementation</h3><p>RemoteControl 表示遥控器，指代 Abstraction。</p>
<p>TV 表示电视，指代 Implementor。</p>
<p>桥接模式将遥控器和电视分离开来，从而可以独立改变遥控器或者电视的实现。</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">abstract</span> <span class="class"><span class="keyword">class</span> <span class="title">TV</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">abstract</span> <span class="keyword">void</span> <span class="title">on</span><span class="params">()</span></span>;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">abstract</span> <span class="keyword">void</span> <span class="title">off</span><span class="params">()</span></span>;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">abstract</span> <span class="keyword">void</span> <span class="title">tuneChannel</span><span class="params">()</span></span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Sony</span> <span class="keyword">extends</span> <span class="title">TV</span> </span>&#123;</span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">on</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;Sony.on()&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">off</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;Sony.off()&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">tuneChannel</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;Sony.tuneChannel()&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">RCA</span> <span class="keyword">extends</span> <span class="title">TV</span> </span>&#123;</span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">on</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;RCA.on()&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">off</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;RCA.off()&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">tuneChannel</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;RCA.tuneChannel()&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">abstract</span> <span class="class"><span class="keyword">class</span> <span class="title">RemoteControl</span> </span>&#123;</span><br><span class="line">    <span class="keyword">protected</span> TV tv;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="title">RemoteControl</span><span class="params">(TV tv)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">this</span>.tv = tv;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">abstract</span> <span class="keyword">void</span> <span class="title">on</span><span class="params">()</span></span>;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">abstract</span> <span class="keyword">void</span> <span class="title">off</span><span class="params">()</span></span>;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">abstract</span> <span class="keyword">void</span> <span class="title">tuneChannel</span><span class="params">()</span></span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">ConcreteRemoteControl1</span> <span class="keyword">extends</span> <span class="title">RemoteControl</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="title">ConcreteRemoteControl1</span><span class="params">(TV tv)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">super</span>(tv);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">on</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;ConcreteRemoteControl1.on()&quot;</span>);</span><br><span class="line">        tv.on();</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">off</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;ConcreteRemoteControl1.off()&quot;</span>);</span><br><span class="line">        tv.off();</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">tuneChannel</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;ConcreteRemoteControl1.tuneChannel()&quot;</span>);</span><br><span class="line">        tv.tuneChannel();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">ConcreteRemoteControl2</span> <span class="keyword">extends</span> <span class="title">RemoteControl</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="title">ConcreteRemoteControl2</span><span class="params">(TV tv)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">super</span>(tv);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">on</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;ConcreteRemoteControl2.on()&quot;</span>);</span><br><span class="line">        tv.on();</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">off</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;ConcreteRemoteControl2.off()&quot;</span>);</span><br><span class="line">        tv.off();</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">tuneChannel</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;ConcreteRemoteControl2.tuneChannel()&quot;</span>);</span><br><span class="line">        tv.tuneChannel();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Client</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">        RemoteControl remoteControl1 = <span class="keyword">new</span> ConcreteRemoteControl1(<span class="keyword">new</span> RCA());</span><br><span class="line">        remoteControl1.on();</span><br><span class="line">        remoteControl1.off();</span><br><span class="line">        remoteControl1.tuneChannel();</span><br><span class="line">        RemoteControl remoteControl2 = <span class="keyword">new</span> ConcreteRemoteControl2(<span class="keyword">new</span> Sony());</span><br><span class="line">         remoteControl2.on();</span><br><span class="line">         remoteControl2.off();</span><br><span class="line">         remoteControl2.tuneChannel();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h3 id="JDK-16"><a href="#JDK-16" class="headerlink" title="JDK"></a>JDK</h3><ul>
<li>AWT (It provides an abstraction layer which maps onto the native OS the windowing support.)</li>
<li>JDBC</li>
</ul>
<h2 id="3-组合（Composite）"><a href="#3-组合（Composite）" class="headerlink" title="3. 组合（Composite）"></a>3. 组合（Composite）</h2><h3 id="Intent-20"><a href="#Intent-20" class="headerlink" title="Intent"></a>Intent</h3><p>将对象组合成树形结构来表示“整体/部分”层次关系，允许用户以相同的方式处理单独对象和组合对象。</p>
<h3 id="Class-Diagram-20"><a href="#Class-Diagram-20" class="headerlink" title="Class Diagram"></a>Class Diagram</h3><p>组件（Component）类是组合类（Composite）和叶子类（Leaf）的父类，可以把组合类看成是树的中间节点。</p>
<p>组合对象拥有一个或者多个组件对象，因此组合对象的操作可以委托给组件对象去处理，而组件对象可以是另一个组合对象或者叶子对象。</p>
<div align="center"> <img src= "" data-lazy-src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/2b8bfd57-b4d1-4a75-bfb0-bcf1fba4014a.png"/> </div><br>

<h3 id="Implementation-20"><a href="#Implementation-20" class="headerlink" title="Implementation"></a>Implementation</h3><figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">abstract</span> <span class="class"><span class="keyword">class</span> <span class="title">Component</span> </span>&#123;</span><br><span class="line">    <span class="keyword">protected</span> String name;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="title">Component</span><span class="params">(String name)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">this</span>.name = name;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">print</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        print(<span class="number">0</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">abstract</span> <span class="keyword">void</span> <span class="title">print</span><span class="params">(<span class="keyword">int</span> level)</span></span>;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">abstract</span> <span class="keyword">public</span> <span class="keyword">void</span> <span class="title">add</span><span class="params">(Component component)</span></span>;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">abstract</span> <span class="keyword">public</span> <span class="keyword">void</span> <span class="title">remove</span><span class="params">(Component component)</span></span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Composite</span> <span class="keyword">extends</span> <span class="title">Component</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">private</span> List&lt;Component&gt; child;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="title">Composite</span><span class="params">(String name)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">super</span>(name);</span><br><span class="line">        child = <span class="keyword">new</span> ArrayList&lt;&gt;();</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">void</span> <span class="title">print</span><span class="params">(<span class="keyword">int</span> level)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i &lt; level; i++) &#123;</span><br><span class="line">            System.out.print(<span class="string">&quot;--&quot;</span>);</span><br><span class="line">        &#125;</span><br><span class="line">        System.out.println(<span class="string">&quot;Composite:&quot;</span> + name);</span><br><span class="line">        <span class="keyword">for</span> (Component component : child) &#123;</span><br><span class="line">            component.print(level + <span class="number">1</span>);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">add</span><span class="params">(Component component)</span> </span>&#123;</span><br><span class="line">        child.add(component);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">remove</span><span class="params">(Component component)</span> </span>&#123;</span><br><span class="line">        child.remove(component);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Leaf</span> <span class="keyword">extends</span> <span class="title">Component</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="title">Leaf</span><span class="params">(String name)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">super</span>(name);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">void</span> <span class="title">print</span><span class="params">(<span class="keyword">int</span> level)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i &lt; level; i++) &#123;</span><br><span class="line">            System.out.print(<span class="string">&quot;--&quot;</span>);</span><br><span class="line">        &#125;</span><br><span class="line">        System.out.println(<span class="string">&quot;left:&quot;</span> + name);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">add</span><span class="params">(Component component)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">throw</span> <span class="keyword">new</span> UnsupportedOperationException(); <span class="comment">// 牺牲透明性换取单一职责原则，这样就不用考虑是叶子节点还是组合节点</span></span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">remove</span><span class="params">(Component component)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">throw</span> <span class="keyword">new</span> UnsupportedOperationException();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Client</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">        Composite root = <span class="keyword">new</span> Composite(<span class="string">&quot;root&quot;</span>);</span><br><span class="line">        Component node1 = <span class="keyword">new</span> Leaf(<span class="string">&quot;1&quot;</span>);</span><br><span class="line">        Component node2 = <span class="keyword">new</span> Composite(<span class="string">&quot;2&quot;</span>);</span><br><span class="line">        Component node3 = <span class="keyword">new</span> Leaf(<span class="string">&quot;3&quot;</span>);</span><br><span class="line">        root.add(node1);</span><br><span class="line">        root.add(node2);</span><br><span class="line">        root.add(node3);</span><br><span class="line">        Component node21 = <span class="keyword">new</span> Leaf(<span class="string">&quot;21&quot;</span>);</span><br><span class="line">        Component node22 = <span class="keyword">new</span> Composite(<span class="string">&quot;22&quot;</span>);</span><br><span class="line">        node2.add(node21);</span><br><span class="line">        node2.add(node22);</span><br><span class="line">        Component node221 = <span class="keyword">new</span> Leaf(<span class="string">&quot;221&quot;</span>);</span><br><span class="line">        node22.add(node221);</span><br><span class="line">        root.print();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight html"><table><tr><td class="code"><pre><span class="line">Composite:root</span><br><span class="line">--left:1</span><br><span class="line">--Composite:2</span><br><span class="line">----left:21</span><br><span class="line">----Composite:22</span><br><span class="line">------left:221</span><br><span class="line">--left:3</span><br></pre></td></tr></table></figure>

<h3 id="JDK-17"><a href="#JDK-17" class="headerlink" title="JDK"></a>JDK</h3><ul>
<li>javax.swing.JComponent#add(Component)</li>
<li>java.awt.Container#add(Component)</li>
<li>java.util.Map#putAll(Map)</li>
<li>java.util.List#addAll(Collection)</li>
<li>java.util.Set#addAll(Collection)</li>
</ul>
<h2 id="4-装饰（Decorator）"><a href="#4-装饰（Decorator）" class="headerlink" title="4. 装饰（Decorator）"></a>4. 装饰（Decorator）</h2><h3 id="Intent-21"><a href="#Intent-21" class="headerlink" title="Intent"></a>Intent</h3><p>为对象动态添加功能。</p>
<h3 id="Class-Diagram-21"><a href="#Class-Diagram-21" class="headerlink" title="Class Diagram"></a>Class Diagram</h3><p>装饰者（Decorator）和具体组件（ConcreteComponent）都继承自组件（Component），具体组件的方法实现不需要依赖于其它对象，而装饰者组合了一个组件，这样它可以装饰其它装饰者或者具体组件。所谓装饰，就是把这个装饰者套在被装饰者之上，从而动态扩展被装饰者的功能。装饰者的方法有一部分是自己的，这属于它的功能，然后调用被装饰者的方法实现，从而也保留了被装饰者的功能。可以看到，具体组件应当是装饰层次的最低层，因为只有具体组件的方法实现不需要依赖于其它对象。</p>
<div align="center"> <img src= "" data-lazy-src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/6b833bc2-517a-4270-8a5e-0a5f6df8cd96.png"/> </div><br>

<h3 id="Implementation-21"><a href="#Implementation-21" class="headerlink" title="Implementation"></a>Implementation</h3><p>设计不同种类的饮料，饮料可以添加配料，比如可以添加牛奶，并且支持动态添加新配料。每增加一种配料，该饮料的价格就会增加，要求计算一种饮料的价格。</p>
<p>下图表示在 DarkRoast 饮料上新增新添加 Mocha 配料，之后又添加了 Whip 配料。DarkRoast 被 Mocha 包裹，Mocha 又被 Whip 包裹。它们都继承自相同父类，都有 cost() 方法，外层类的 cost() 方法调用了内层类的 cost() 方法。</p>
<div align="center"> <img src= "" data-lazy-src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/c9cfd600-bc91-4f3a-9f99-b42f88a5bb24.jpg" width="600"/> </div><br>

<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">interface</span> <span class="title">Beverage</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">double</span> <span class="title">cost</span><span class="params">()</span></span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">DarkRoast</span> <span class="keyword">implements</span> <span class="title">Beverage</span> </span>&#123;</span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">double</span> <span class="title">cost</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="number">1</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">HouseBlend</span> <span class="keyword">implements</span> <span class="title">Beverage</span> </span>&#123;</span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">double</span> <span class="title">cost</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="number">1</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">abstract</span> <span class="class"><span class="keyword">class</span> <span class="title">CondimentDecorator</span> <span class="keyword">implements</span> <span class="title">Beverage</span> </span>&#123;</span><br><span class="line">    <span class="keyword">protected</span> Beverage beverage;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Milk</span> <span class="keyword">extends</span> <span class="title">CondimentDecorator</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="title">Milk</span><span class="params">(Beverage beverage)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">this</span>.beverage = beverage;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">double</span> <span class="title">cost</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="number">1</span> + beverage.cost();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Mocha</span> <span class="keyword">extends</span> <span class="title">CondimentDecorator</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="title">Mocha</span><span class="params">(Beverage beverage)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">this</span>.beverage = beverage;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">double</span> <span class="title">cost</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="number">1</span> + beverage.cost();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Client</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">        Beverage beverage = <span class="keyword">new</span> HouseBlend();</span><br><span class="line">        beverage = <span class="keyword">new</span> Mocha(beverage);</span><br><span class="line">        beverage = <span class="keyword">new</span> Milk(beverage);</span><br><span class="line">        System.out.println(beverage.cost());</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight html"><table><tr><td class="code"><pre><span class="line">3.0</span><br></pre></td></tr></table></figure>

<h3 id="设计原则"><a href="#设计原则" class="headerlink" title="设计原则"></a>设计原则</h3><p>类应该对扩展开放，对修改关闭：也就是添加新功能时不需要修改代码。饮料可以动态添加新的配料，而不需要去修改饮料的代码。</p>
<p>不可能把所有的类设计成都满足这一原则，应当把该原则应用于最有可能发生改变的地方。</p>
<h3 id="JDK-18"><a href="#JDK-18" class="headerlink" title="JDK"></a>JDK</h3><ul>
<li>java.io.BufferedInputStream(InputStream)</li>
<li>java.io.DataInputStream(InputStream)</li>
<li>java.io.BufferedOutputStream(OutputStream)</li>
<li>java.util.zip.ZipOutputStream(OutputStream)</li>
<li>java.util.Collections#checked<a href="">List|Map|Set|SortedSet|SortedMap</a></li>
</ul>
<h2 id="5-外观（Facade）"><a href="#5-外观（Facade）" class="headerlink" title="5. 外观（Facade）"></a>5. 外观（Facade）</h2><h3 id="Intent-22"><a href="#Intent-22" class="headerlink" title="Intent"></a>Intent</h3><p>提供了一个统一的接口，用来访问子系统中的一群接口，从而让子系统更容易使用。</p>
<h3 id="Class-Diagram-22"><a href="#Class-Diagram-22" class="headerlink" title="Class Diagram"></a>Class Diagram</h3><div align="center"> <img src= "" data-lazy-src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/f9978fa6-9f49-4a0f-8540-02d269ac448f.png"/> </div><br>

<h3 id="Implementation-22"><a href="#Implementation-22" class="headerlink" title="Implementation"></a>Implementation</h3><p>观看电影需要操作很多电器，使用外观模式实现一键看电影功能。</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">SubSystem</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">turnOnTV</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;turnOnTV()&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">setCD</span><span class="params">(String cd)</span> </span>&#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;setCD( &quot;</span> + cd + <span class="string">&quot; )&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">startWatching</span><span class="params">()</span></span>&#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;startWatching()&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Facade</span> </span>&#123;</span><br><span class="line">    <span class="keyword">private</span> SubSystem subSystem = <span class="keyword">new</span> SubSystem();</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">watchMovie</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        subSystem.turnOnTV();</span><br><span class="line">        subSystem.setCD(<span class="string">&quot;a movie&quot;</span>);</span><br><span class="line">        subSystem.startWatching();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Client</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">        Facade facade = <span class="keyword">new</span> Facade();</span><br><span class="line">        facade.watchMovie();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h3 id="设计原则-1"><a href="#设计原则-1" class="headerlink" title="设计原则"></a>设计原则</h3><p>最少知识原则：只和你的密友谈话。也就是说客户对象所需要交互的对象应当尽可能少。</p>
<h2 id="6-享元（Flyweight）"><a href="#6-享元（Flyweight）" class="headerlink" title="6. 享元（Flyweight）"></a>6. 享元（Flyweight）</h2><h3 id="Intent-23"><a href="#Intent-23" class="headerlink" title="Intent"></a>Intent</h3><p>利用共享的方式来支持大量细粒度的对象，这些对象一部分内部状态是相同的。</p>
<h3 id="Class-Diagram-23"><a href="#Class-Diagram-23" class="headerlink" title="Class Diagram"></a>Class Diagram</h3><ul>
<li>Flyweight：享元对象</li>
<li>IntrinsicState：内部状态，享元对象共享内部状态</li>
<li>ExtrinsicState：外部状态，每个享元对象的外部状态不同</li>
</ul>
<div align="center"> <img src= "" data-lazy-src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/5f5c22d5-9c0e-49e1-b5b0-6cc7032724d4.png"/> </div><br>

<h3 id="Implementation-23"><a href="#Implementation-23" class="headerlink" title="Implementation"></a>Implementation</h3><figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">interface</span> <span class="title">Flyweight</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">void</span> <span class="title">doOperation</span><span class="params">(String extrinsicState)</span></span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">ConcreteFlyweight</span> <span class="keyword">implements</span> <span class="title">Flyweight</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">private</span> String intrinsicState;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="title">ConcreteFlyweight</span><span class="params">(String intrinsicState)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">this</span>.intrinsicState = intrinsicState;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">doOperation</span><span class="params">(String extrinsicState)</span> </span>&#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;Object address: &quot;</span> + System.identityHashCode(<span class="keyword">this</span>));</span><br><span class="line">        System.out.println(<span class="string">&quot;IntrinsicState: &quot;</span> + intrinsicState);</span><br><span class="line">        System.out.println(<span class="string">&quot;ExtrinsicState: &quot;</span> + extrinsicState);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">FlyweightFactory</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">private</span> HashMap&lt;String, Flyweight&gt; flyweights = <span class="keyword">new</span> HashMap&lt;&gt;();</span><br><span class="line"></span><br><span class="line">    <span class="function">Flyweight <span class="title">getFlyweight</span><span class="params">(String intrinsicState)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">if</span> (!flyweights.containsKey(intrinsicState)) &#123;</span><br><span class="line">            Flyweight flyweight = <span class="keyword">new</span> ConcreteFlyweight(intrinsicState);</span><br><span class="line">            flyweights.put(intrinsicState, flyweight);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> flyweights.get(intrinsicState);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Client</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">        FlyweightFactory factory = <span class="keyword">new</span> FlyweightFactory();</span><br><span class="line">        Flyweight flyweight1 = factory.getFlyweight(<span class="string">&quot;aa&quot;</span>);</span><br><span class="line">        Flyweight flyweight2 = factory.getFlyweight(<span class="string">&quot;aa&quot;</span>);</span><br><span class="line">        flyweight1.doOperation(<span class="string">&quot;x&quot;</span>);</span><br><span class="line">        flyweight2.doOperation(<span class="string">&quot;y&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight html"><table><tr><td class="code"><pre><span class="line">Object address: 1163157884</span><br><span class="line">IntrinsicState: aa</span><br><span class="line">ExtrinsicState: x</span><br><span class="line">Object address: 1163157884</span><br><span class="line">IntrinsicState: aa</span><br><span class="line">ExtrinsicState: y</span><br></pre></td></tr></table></figure>

<h3 id="JDK-19"><a href="#JDK-19" class="headerlink" title="JDK"></a>JDK</h3><p>Java 利用缓存来加速大量小对象的访问时间。</p>
<ul>
<li>java.lang.Integer#valueOf(int)</li>
<li>java.lang.Boolean#valueOf(boolean)</li>
<li>java.lang.Byte#valueOf(byte)</li>
<li>java.lang.Character#valueOf(char)</li>
</ul>
<h2 id="7-代理（Proxy）"><a href="#7-代理（Proxy）" class="headerlink" title="7. 代理（Proxy）"></a>7. 代理（Proxy）</h2><h3 id="Intent-24"><a href="#Intent-24" class="headerlink" title="Intent"></a>Intent</h3><p>控制对其它对象的访问。</p>
<h3 id="Class-Diagram-24"><a href="#Class-Diagram-24" class="headerlink" title="Class Diagram"></a>Class Diagram</h3><p>代理有以下四类：</p>
<ul>
<li>远程代理（Remote Proxy）：控制对远程对象（不同地址空间）的访问，它负责将请求及其参数进行编码，并向不同地址空间中的对象发送已经编码的请求。</li>
<li>虚拟代理（Virtual Proxy）：根据需要创建开销很大的对象，它可以缓存实体的附加信息，以便延迟对它的访问，例如在网站加载一个很大图片时，不能马上完成，可以用虚拟代理缓存图片的大小信息，然后生成一张临时图片代替原始图片。</li>
<li>保护代理（Protection Proxy）：按权限控制对象的访问，它负责检查调用者是否具有实现一个请求所必须的访问权限。</li>
<li>智能代理（Smart Reference）：取代了简单的指针，它在访问对象时执行一些附加操作：记录对象的引用次数；当第一次引用一个对象时，将它装入内存；在访问一个实际对象前，检查是否已经锁定了它，以确保其它对象不能改变它。</li>
</ul>
<div align="center"> <img src= "" data-lazy-src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/9b679ff5-94c6-48a7-b9b7-2ea868e828ed.png"/> </div><br>

<h3 id="Implementation-24"><a href="#Implementation-24" class="headerlink" title="Implementation"></a>Implementation</h3><p>以下是一个虚拟代理的实现，模拟了图片延迟加载的情况下使用与图片大小相等的临时内容去替换原始图片，直到图片加载完成才将图片显示出来。</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">interface</span> <span class="title">Image</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">void</span> <span class="title">showImage</span><span class="params">()</span></span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">HighResolutionImage</span> <span class="keyword">implements</span> <span class="title">Image</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">private</span> URL imageURL;</span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">long</span> startTime;</span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">int</span> height;</span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">int</span> width;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">getHeight</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> height;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">getWidth</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> width;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="title">HighResolutionImage</span><span class="params">(URL imageURL)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">this</span>.imageURL = imageURL;</span><br><span class="line">        <span class="keyword">this</span>.startTime = System.currentTimeMillis();</span><br><span class="line">        <span class="keyword">this</span>.width = <span class="number">600</span>;</span><br><span class="line">        <span class="keyword">this</span>.height = <span class="number">600</span>;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">isLoad</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="comment">// 模拟图片加载，延迟 3s 加载完成</span></span><br><span class="line">        <span class="keyword">long</span> endTime = System.currentTimeMillis();</span><br><span class="line">        <span class="keyword">return</span> endTime - startTime &gt; <span class="number">3000</span>;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">showImage</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;Real Image: &quot;</span> + imageURL);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">ImageProxy</span> <span class="keyword">implements</span> <span class="title">Image</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">private</span> HighResolutionImage highResolutionImage;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="title">ImageProxy</span><span class="params">(HighResolutionImage highResolutionImage)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">this</span>.highResolutionImage = highResolutionImage;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">showImage</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">while</span> (!highResolutionImage.isLoad()) &#123;</span><br><span class="line">            <span class="keyword">try</span> &#123;</span><br><span class="line">                System.out.println(<span class="string">&quot;Temp Image: &quot;</span> + highResolutionImage.getWidth() + <span class="string">&quot; &quot;</span> + highResolutionImage.getHeight());</span><br><span class="line">                Thread.sleep(<span class="number">100</span>);</span><br><span class="line">            &#125; <span class="keyword">catch</span> (InterruptedException e) &#123;</span><br><span class="line">                e.printStackTrace();</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        highResolutionImage.showImage();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">ImageViewer</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> <span class="keyword">throws</span> Exception </span>&#123;</span><br><span class="line">        String image = <span class="string">&quot;http://image.jpg&quot;</span>;</span><br><span class="line">        URL url = <span class="keyword">new</span> URL(image);</span><br><span class="line">        HighResolutionImage highResolutionImage = <span class="keyword">new</span> HighResolutionImage(url);</span><br><span class="line">        ImageProxy imageProxy = <span class="keyword">new</span> ImageProxy(highResolutionImage);</span><br><span class="line">        imageProxy.showImage();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h3 id="JDK-20"><a href="#JDK-20" class="headerlink" title="JDK"></a>JDK</h3><ul>
<li>java.lang.reflect.Proxy</li>
<li>RMI</li>
</ul>
<h1 id="参考资料"><a href="#参考资料" class="headerlink" title="参考资料"></a>参考资料</h1><ul>
<li>弗里曼. Head First 设计模式 [M]. 中国电力出版社, 2007.</li>
<li>Gamma E. 设计模式: 可复用面向对象软件的基础 [M]. 机械工业出版社, 2007.</li>
<li>Bloch J. Effective java[M]. Addison-Wesley Professional, 2017.</li>
<li><a target="_blank" rel="noopener" href="http://www.oodesign.com/">Design Patterns</a></li>
<li><a target="_blank" rel="noopener" href="http://java-design-patterns.com/">Design patterns implemented in Java</a></li>
<li><a target="_blank" rel="noopener" href="http://www.programering.com/a/MTNxAzMwATY.html">The breakdown of design patterns in JDK</a></li>
</ul>
</article><div class="post-copyright"><div class="post-copyright__author"><span class="post-copyright-meta">文章作者: </span><span class="post-copyright-info"><a href="mailto:undefined">Zhang Shuo</a></span></div><div class="post-copyright__type"><span class="post-copyright-meta">文章链接: </span><span class="post-copyright-info"><a href="https://zhang-shuo-fr.gitee.io/hexo3/2021/12/06/notes/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/">https://zhang-shuo-fr.gitee.io/hexo3/2021/12/06/notes/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/</a></span></div><div class="post-copyright__notice"><span class="post-copyright-meta">版权声明: </span><span class="post-copyright-info">本博客所有文章除特别声明外，均采用 <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/" target="_blank">CC BY-NC-SA 4.0</a> 许可协议。转载请注明来自 <a href="https://zhang-shuo-fr.gitee.io/hexo3" target="_blank">Zhang Shuo'blog</a>！</span></div></div><div class="tag_share"><div class="post-meta__tag-list"><a class="post-meta__tags" href="/hexo3/tags/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/">设计模式</a></div><div class="post_share"><div class="social-share" data-image="/hexo3/img/20.jpg" data-sites="facebook,twitter,wechat,weibo,qq"></div><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/social-share.js/dist/css/share.min.css" media="print" onload="this.media='all'"><script src="https://cdn.jsdelivr.net/npm/social-share.js/dist/js/social-share.min.js" defer></script></div></div><div class="post-reward"><div class="reward-button button--animated"><i class="fas fa-qrcode"></i> 打赏</div><div class="reward-main"><ul class="reward-all"><li class="reward-item"><a href="/hexo3/img/wechat.jpg" target="_blank"><img class="post-qr-code-img" src= "" data-lazy-src="/hexo3/img/wechat.jpg" alt="微信"/></a><div class="post-qr-code-desc">微信</div></li><li class="reward-item"><a href="/hexo3/img/alipay.jpg" target="_blank"><img class="post-qr-code-img" src= "" data-lazy-src="/hexo3/img/alipay.jpg" alt="支付宝"/></a><div class="post-qr-code-desc">支付宝</div></li></ul></div></div><nav class="pagination-post" id="pagination"><div class="next-post pull-full"><a href="/hexo3/2021/12/06/notes/Java%20%E5%B9%B6%E5%8F%91/"><img class="next-cover" src= "" data-lazy-src="/hexo3/img/15.jpg" onerror="onerror=null;src='/hexo3/img/404.jpg'" alt="cover of next post"><div class="pagination-info"><div class="label">下一篇</div><div class="next_info">Java并发</div></div></a></div></nav><div class="relatedPosts"><div class="headline"><i class="fas fa-thumbs-up fa-fw"></i><span>相关推荐</span></div><div class="relatedPosts-list"><div><a href="/hexo3/2021/12/06/notes/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%20%20-%20%E5%8D%95%E4%BE%8B/" title="设计模式  - 单例"><img class="cover" src= "" data-lazy-src="/hexo3/img/12.jpg" alt="cover"><div class="content is-center"><div class="date"><i class="far fa-calendar-alt fa-fw"></i> 2021-12-06</div><div class="title">设计模式  - 单例</div></div></a></div><div><a href="/hexo3/2021/12/06/notes/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%20-%20%E4%B8%AD%E4%BB%8B%E8%80%85/" title="设计模式 - 中介者"><img class="cover" src= "" data-lazy-src="/hexo3/img/20.jpg" alt="cover"><div class="content is-center"><div class="date"><i class="far fa-calendar-alt fa-fw"></i> 2021-12-06</div><div class="title">设计模式 - 中介者</div></div></a></div><div><a href="/hexo3/2021/12/06/notes/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%20-%20%E4%BB%A3%E7%90%86/" title="设计模式 - 代理"><img class="cover" src= "" data-lazy-src="/hexo3/img/11.jpg" alt="cover"><div class="content is-center"><div class="date"><i class="far fa-calendar-alt fa-fw"></i> 2021-12-06</div><div class="title">设计模式 - 代理</div></div></a></div><div><a href="/hexo3/2021/12/06/notes/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%20-%20%E5%8E%9F%E5%9E%8B%E6%A8%A1%E5%BC%8F/" title="设计模式 - 原型模式"><img class="cover" src= "" data-lazy-src="/hexo3/img/17.jpg" alt="cover"><div class="content is-center"><div class="date"><i class="far fa-calendar-alt fa-fw"></i> 2021-12-06</div><div class="title">设计模式 - 原型模式</div></div></a></div><div><a href="/hexo3/2021/12/06/notes/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%20-%20%E4%BA%AB%E5%85%83/" title="设计模式 - 享元"><img class="cover" src= "" data-lazy-src="/hexo3/img/4.jpg" alt="cover"><div class="content is-center"><div class="date"><i class="far fa-calendar-alt fa-fw"></i> 2021-12-06</div><div class="title">设计模式 - 享元</div></div></a></div><div><a href="/hexo3/2021/12/06/notes/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%20-%20%E5%91%BD%E4%BB%A4/" title="设计模式 - 命令"><img class="cover" src= "" data-lazy-src="/hexo3/img/20.jpg" alt="cover"><div class="content is-center"><div class="date"><i class="far fa-calendar-alt fa-fw"></i> 2021-12-06</div><div class="title">设计模式 - 命令</div></div></a></div></div></div></div><div class="aside-content" id="aside-content"><div class="sticky_layout"><div class="card-widget" id="card-toc"><div class="item-headline"><i class="fas fa-stream"></i><span>目录</span></div><div class="toc-content"><ol class="toc"><li class="toc-item toc-level-1"><a class="toc-link" href="#%E4%B8%80%E3%80%81%E6%A6%82%E8%BF%B0"><span class="toc-number">1.</span> <span class="toc-text">一、概述</span></a></li><li class="toc-item toc-level-1"><a class="toc-link" href="#%E4%BA%8C%E3%80%81%E5%88%9B%E5%BB%BA%E5%9E%8B"><span class="toc-number">2.</span> <span class="toc-text">二、创建型</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#1-%E5%8D%95%E4%BE%8B%EF%BC%88Singleton%EF%BC%89"><span class="toc-number">2.1.</span> <span class="toc-text">1. 单例（Singleton）</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#Intent"><span class="toc-number">2.1.1.</span> <span class="toc-text">Intent</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Class-Diagram"><span class="toc-number">2.1.2.</span> <span class="toc-text">Class Diagram</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Implementation"><span class="toc-number">2.1.3.</span> <span class="toc-text">Implementation</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#%E2%85%A0-%E6%87%92%E6%B1%89%E5%BC%8F-%E7%BA%BF%E7%A8%8B%E4%B8%8D%E5%AE%89%E5%85%A8"><span class="toc-number">2.1.3.1.</span> <span class="toc-text">Ⅰ 懒汉式-线程不安全</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E2%85%A1-%E9%A5%BF%E6%B1%89%E5%BC%8F-%E7%BA%BF%E7%A8%8B%E5%AE%89%E5%85%A8"><span class="toc-number">2.1.3.2.</span> <span class="toc-text">Ⅱ 饿汉式-线程安全</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E2%85%A2-%E6%87%92%E6%B1%89%E5%BC%8F-%E7%BA%BF%E7%A8%8B%E5%AE%89%E5%85%A8"><span class="toc-number">2.1.3.3.</span> <span class="toc-text">Ⅲ 懒汉式-线程安全</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E2%85%A3-%E5%8F%8C%E9%87%8D%E6%A0%A1%E9%AA%8C%E9%94%81-%E7%BA%BF%E7%A8%8B%E5%AE%89%E5%85%A8"><span class="toc-number">2.1.3.4.</span> <span class="toc-text">Ⅳ 双重校验锁-线程安全</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E2%85%A4-%E9%9D%99%E6%80%81%E5%86%85%E9%83%A8%E7%B1%BB%E5%AE%9E%E7%8E%B0"><span class="toc-number">2.1.3.5.</span> <span class="toc-text">Ⅴ 静态内部类实现</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E2%85%A5-%E6%9E%9A%E4%B8%BE%E5%AE%9E%E7%8E%B0"><span class="toc-number">2.1.3.6.</span> <span class="toc-text">Ⅵ 枚举实现</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Examples"><span class="toc-number">2.1.4.</span> <span class="toc-text">Examples</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#JDK"><span class="toc-number">2.1.5.</span> <span class="toc-text">JDK</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#2-%E7%AE%80%E5%8D%95%E5%B7%A5%E5%8E%82%EF%BC%88Simple-Factory%EF%BC%89"><span class="toc-number">2.2.</span> <span class="toc-text">2. 简单工厂（Simple Factory）</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#Intent-1"><span class="toc-number">2.2.1.</span> <span class="toc-text">Intent</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Class-Diagram-1"><span class="toc-number">2.2.2.</span> <span class="toc-text">Class Diagram</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Implementation-1"><span class="toc-number">2.2.3.</span> <span class="toc-text">Implementation</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#3-%E5%B7%A5%E5%8E%82%E6%96%B9%E6%B3%95%EF%BC%88Factory-Method%EF%BC%89"><span class="toc-number">2.3.</span> <span class="toc-text">3. 工厂方法（Factory Method）</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#Intent-2"><span class="toc-number">2.3.1.</span> <span class="toc-text">Intent</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Class-Diagram-2"><span class="toc-number">2.3.2.</span> <span class="toc-text">Class Diagram</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Implementation-2"><span class="toc-number">2.3.3.</span> <span class="toc-text">Implementation</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#JDK-1"><span class="toc-number">2.3.4.</span> <span class="toc-text">JDK</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#4-%E6%8A%BD%E8%B1%A1%E5%B7%A5%E5%8E%82%EF%BC%88Abstract-Factory%EF%BC%89"><span class="toc-number">2.4.</span> <span class="toc-text">4. 抽象工厂（Abstract Factory）</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#Intent-3"><span class="toc-number">2.4.1.</span> <span class="toc-text">Intent</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Class-Diagram-3"><span class="toc-number">2.4.2.</span> <span class="toc-text">Class Diagram</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Implementation-3"><span class="toc-number">2.4.3.</span> <span class="toc-text">Implementation</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#JDK-2"><span class="toc-number">2.4.4.</span> <span class="toc-text">JDK</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#5-%E7%94%9F%E6%88%90%E5%99%A8%EF%BC%88Builder%EF%BC%89"><span class="toc-number">2.5.</span> <span class="toc-text">5. 生成器（Builder）</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#Intent-4"><span class="toc-number">2.5.1.</span> <span class="toc-text">Intent</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Class-Diagram-4"><span class="toc-number">2.5.2.</span> <span class="toc-text">Class Diagram</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Implementation-4"><span class="toc-number">2.5.3.</span> <span class="toc-text">Implementation</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#JDK-3"><span class="toc-number">2.5.4.</span> <span class="toc-text">JDK</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#6-%E5%8E%9F%E5%9E%8B%E6%A8%A1%E5%BC%8F%EF%BC%88Prototype%EF%BC%89"><span class="toc-number">2.6.</span> <span class="toc-text">6. 原型模式（Prototype）</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#Intent-5"><span class="toc-number">2.6.1.</span> <span class="toc-text">Intent</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Class-Diagram-5"><span class="toc-number">2.6.2.</span> <span class="toc-text">Class Diagram</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Implementation-5"><span class="toc-number">2.6.3.</span> <span class="toc-text">Implementation</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#JDK-4"><span class="toc-number">2.6.4.</span> <span class="toc-text">JDK</span></a></li></ol></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#%E4%B8%89%E3%80%81%E8%A1%8C%E4%B8%BA%E5%9E%8B"><span class="toc-number">3.</span> <span class="toc-text">三、行为型</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#1-%E8%B4%A3%E4%BB%BB%E9%93%BE%EF%BC%88Chain-Of-Responsibility%EF%BC%89"><span class="toc-number">3.1.</span> <span class="toc-text">1. 责任链（Chain Of Responsibility）</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#Intent-6"><span class="toc-number">3.1.1.</span> <span class="toc-text">Intent</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Class-Diagram-6"><span class="toc-number">3.1.2.</span> <span class="toc-text">Class Diagram</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Implementation-6"><span class="toc-number">3.1.3.</span> <span class="toc-text">Implementation</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#JDK-5"><span class="toc-number">3.1.4.</span> <span class="toc-text">JDK</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#2-%E5%91%BD%E4%BB%A4%EF%BC%88Command%EF%BC%89"><span class="toc-number">3.2.</span> <span class="toc-text">2. 命令（Command）</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#Intent-7"><span class="toc-number">3.2.1.</span> <span class="toc-text">Intent</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Class-Diagram-7"><span class="toc-number">3.2.2.</span> <span class="toc-text">Class Diagram</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Implementation-7"><span class="toc-number">3.2.3.</span> <span class="toc-text">Implementation</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#JDK-6"><span class="toc-number">3.2.4.</span> <span class="toc-text">JDK</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#3-%E8%A7%A3%E9%87%8A%E5%99%A8%EF%BC%88Interpreter%EF%BC%89"><span class="toc-number">3.3.</span> <span class="toc-text">3. 解释器（Interpreter）</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#Intent-8"><span class="toc-number">3.3.1.</span> <span class="toc-text">Intent</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Class-Diagram-8"><span class="toc-number">3.3.2.</span> <span class="toc-text">Class Diagram</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Implementation-8"><span class="toc-number">3.3.3.</span> <span class="toc-text">Implementation</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#JDK-7"><span class="toc-number">3.3.4.</span> <span class="toc-text">JDK</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#4-%E8%BF%AD%E4%BB%A3%E5%99%A8%EF%BC%88Iterator%EF%BC%89"><span class="toc-number">3.4.</span> <span class="toc-text">4. 迭代器（Iterator）</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#Intent-9"><span class="toc-number">3.4.1.</span> <span class="toc-text">Intent</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Class-Diagram-9"><span class="toc-number">3.4.2.</span> <span class="toc-text">Class Diagram</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Implementation-9"><span class="toc-number">3.4.3.</span> <span class="toc-text">Implementation</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#JDK-8"><span class="toc-number">3.4.4.</span> <span class="toc-text">JDK</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#5-%E4%B8%AD%E4%BB%8B%E8%80%85%EF%BC%88Mediator%EF%BC%89"><span class="toc-number">3.5.</span> <span class="toc-text">5. 中介者（Mediator）</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#Intent-10"><span class="toc-number">3.5.1.</span> <span class="toc-text">Intent</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Class-Diagram-10"><span class="toc-number">3.5.2.</span> <span class="toc-text">Class Diagram</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Implementation-10"><span class="toc-number">3.5.3.</span> <span class="toc-text">Implementation</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#JDK-9"><span class="toc-number">3.5.4.</span> <span class="toc-text">JDK</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#6-%E5%A4%87%E5%BF%98%E5%BD%95%EF%BC%88Memento%EF%BC%89"><span class="toc-number">3.6.</span> <span class="toc-text">6. 备忘录（Memento）</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#Intent-11"><span class="toc-number">3.6.1.</span> <span class="toc-text">Intent</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Class-Diagram-11"><span class="toc-number">3.6.2.</span> <span class="toc-text">Class Diagram</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Implementation-11"><span class="toc-number">3.6.3.</span> <span class="toc-text">Implementation</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#JDK-10"><span class="toc-number">3.6.4.</span> <span class="toc-text">JDK</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#7-%E8%A7%82%E5%AF%9F%E8%80%85%EF%BC%88Observer%EF%BC%89"><span class="toc-number">3.7.</span> <span class="toc-text">7. 观察者（Observer）</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#Intent-12"><span class="toc-number">3.7.1.</span> <span class="toc-text">Intent</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Class-Diagram-12"><span class="toc-number">3.7.2.</span> <span class="toc-text">Class Diagram</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Implementation-12"><span class="toc-number">3.7.3.</span> <span class="toc-text">Implementation</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#JDK-11"><span class="toc-number">3.7.4.</span> <span class="toc-text">JDK</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#8-%E7%8A%B6%E6%80%81%EF%BC%88State%EF%BC%89"><span class="toc-number">3.8.</span> <span class="toc-text">8. 状态（State）</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#Intent-13"><span class="toc-number">3.8.1.</span> <span class="toc-text">Intent</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Class-Diagram-13"><span class="toc-number">3.8.2.</span> <span class="toc-text">Class Diagram</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Implementation-13"><span class="toc-number">3.8.3.</span> <span class="toc-text">Implementation</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#9-%E7%AD%96%E7%95%A5%EF%BC%88Strategy%EF%BC%89"><span class="toc-number">3.9.</span> <span class="toc-text">9. 策略（Strategy）</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#Intent-14"><span class="toc-number">3.9.1.</span> <span class="toc-text">Intent</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Class-Diagram-14"><span class="toc-number">3.9.2.</span> <span class="toc-text">Class Diagram</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E4%B8%8E%E7%8A%B6%E6%80%81%E6%A8%A1%E5%BC%8F%E7%9A%84%E6%AF%94%E8%BE%83"><span class="toc-number">3.9.3.</span> <span class="toc-text">与状态模式的比较</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Implementation-14"><span class="toc-number">3.9.4.</span> <span class="toc-text">Implementation</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#JDK-12"><span class="toc-number">3.9.5.</span> <span class="toc-text">JDK</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#10-%E6%A8%A1%E6%9D%BF%E6%96%B9%E6%B3%95%EF%BC%88Template-Method%EF%BC%89"><span class="toc-number">3.10.</span> <span class="toc-text">10. 模板方法（Template Method）</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#Intent-15"><span class="toc-number">3.10.1.</span> <span class="toc-text">Intent</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Class-Diagram-15"><span class="toc-number">3.10.2.</span> <span class="toc-text">Class Diagram</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Implementation-15"><span class="toc-number">3.10.3.</span> <span class="toc-text">Implementation</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#JDK-13"><span class="toc-number">3.10.4.</span> <span class="toc-text">JDK</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#11-%E8%AE%BF%E9%97%AE%E8%80%85%EF%BC%88Visitor%EF%BC%89"><span class="toc-number">3.11.</span> <span class="toc-text">11. 访问者（Visitor）</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#Intent-16"><span class="toc-number">3.11.1.</span> <span class="toc-text">Intent</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Class-Diagram-16"><span class="toc-number">3.11.2.</span> <span class="toc-text">Class Diagram</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Implementation-16"><span class="toc-number">3.11.3.</span> <span class="toc-text">Implementation</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#JDK-14"><span class="toc-number">3.11.4.</span> <span class="toc-text">JDK</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#12-%E7%A9%BA%E5%AF%B9%E8%B1%A1%EF%BC%88Null%EF%BC%89"><span class="toc-number">3.12.</span> <span class="toc-text">12. 空对象（Null）</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#Intent-17"><span class="toc-number">3.12.1.</span> <span class="toc-text">Intent</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Class-Diagram-17"><span class="toc-number">3.12.2.</span> <span class="toc-text">Class Diagram</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Implementation-17"><span class="toc-number">3.12.3.</span> <span class="toc-text">Implementation</span></a></li></ol></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#%E5%9B%9B%E3%80%81%E7%BB%93%E6%9E%84%E5%9E%8B"><span class="toc-number">4.</span> <span class="toc-text">四、结构型</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#1-%E9%80%82%E9%85%8D%E5%99%A8%EF%BC%88Adapter%EF%BC%89"><span class="toc-number">4.1.</span> <span class="toc-text">1. 适配器（Adapter）</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#Intent-18"><span class="toc-number">4.1.1.</span> <span class="toc-text">Intent</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Class-Diagram-18"><span class="toc-number">4.1.2.</span> <span class="toc-text">Class Diagram</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Implementation-18"><span class="toc-number">4.1.3.</span> <span class="toc-text">Implementation</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#JDK-15"><span class="toc-number">4.1.4.</span> <span class="toc-text">JDK</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#2-%E6%A1%A5%E6%8E%A5%EF%BC%88Bridge%EF%BC%89"><span class="toc-number">4.2.</span> <span class="toc-text">2. 桥接（Bridge）</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#Intent-19"><span class="toc-number">4.2.1.</span> <span class="toc-text">Intent</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Class-Diagram-19"><span class="toc-number">4.2.2.</span> <span class="toc-text">Class Diagram</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Implementation-19"><span class="toc-number">4.2.3.</span> <span class="toc-text">Implementation</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#JDK-16"><span class="toc-number">4.2.4.</span> <span class="toc-text">JDK</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#3-%E7%BB%84%E5%90%88%EF%BC%88Composite%EF%BC%89"><span class="toc-number">4.3.</span> <span class="toc-text">3. 组合（Composite）</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#Intent-20"><span class="toc-number">4.3.1.</span> <span class="toc-text">Intent</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Class-Diagram-20"><span class="toc-number">4.3.2.</span> <span class="toc-text">Class Diagram</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Implementation-20"><span class="toc-number">4.3.3.</span> <span class="toc-text">Implementation</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#JDK-17"><span class="toc-number">4.3.4.</span> <span class="toc-text">JDK</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#4-%E8%A3%85%E9%A5%B0%EF%BC%88Decorator%EF%BC%89"><span class="toc-number">4.4.</span> <span class="toc-text">4. 装饰（Decorator）</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#Intent-21"><span class="toc-number">4.4.1.</span> <span class="toc-text">Intent</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Class-Diagram-21"><span class="toc-number">4.4.2.</span> <span class="toc-text">Class Diagram</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Implementation-21"><span class="toc-number">4.4.3.</span> <span class="toc-text">Implementation</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E8%AE%BE%E8%AE%A1%E5%8E%9F%E5%88%99"><span class="toc-number">4.4.4.</span> <span class="toc-text">设计原则</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#JDK-18"><span class="toc-number">4.4.5.</span> <span class="toc-text">JDK</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#5-%E5%A4%96%E8%A7%82%EF%BC%88Facade%EF%BC%89"><span class="toc-number">4.5.</span> <span class="toc-text">5. 外观（Facade）</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#Intent-22"><span class="toc-number">4.5.1.</span> <span class="toc-text">Intent</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Class-Diagram-22"><span class="toc-number">4.5.2.</span> <span class="toc-text">Class Diagram</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Implementation-22"><span class="toc-number">4.5.3.</span> <span class="toc-text">Implementation</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E8%AE%BE%E8%AE%A1%E5%8E%9F%E5%88%99-1"><span class="toc-number">4.5.4.</span> <span class="toc-text">设计原则</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#6-%E4%BA%AB%E5%85%83%EF%BC%88Flyweight%EF%BC%89"><span class="toc-number">4.6.</span> <span class="toc-text">6. 享元（Flyweight）</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#Intent-23"><span class="toc-number">4.6.1.</span> <span class="toc-text">Intent</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Class-Diagram-23"><span class="toc-number">4.6.2.</span> <span class="toc-text">Class Diagram</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Implementation-23"><span class="toc-number">4.6.3.</span> <span class="toc-text">Implementation</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#JDK-19"><span class="toc-number">4.6.4.</span> <span class="toc-text">JDK</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#7-%E4%BB%A3%E7%90%86%EF%BC%88Proxy%EF%BC%89"><span class="toc-number">4.7.</span> <span class="toc-text">7. 代理（Proxy）</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#Intent-24"><span class="toc-number">4.7.1.</span> <span class="toc-text">Intent</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Class-Diagram-24"><span class="toc-number">4.7.2.</span> <span class="toc-text">Class Diagram</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Implementation-24"><span class="toc-number">4.7.3.</span> <span class="toc-text">Implementation</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#JDK-20"><span class="toc-number">4.7.4.</span> <span class="toc-text">JDK</span></a></li></ol></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#%E5%8F%82%E8%80%83%E8%B5%84%E6%96%99"><span class="toc-number">5.</span> <span class="toc-text">参考资料</span></a></li></ol></div></div></div></div></main><footer id="footer" style="background-image: url('/hexo3/img/20.jpg')"><div id="footer-wrap"><div class="copyright">&copy;2020 - 2022 By Zhang Shuo</div><div class="framework-info"><span>框架 </span><a target="_blank" rel="noopener" href="https://hexo.io">Hexo</a><span class="footer-separator">|</span><span>主题 </span><a target="_blank" rel="noopener" href="https://github.com/jerryc127/hexo-theme-butterfly">Butterfly</a></div><div class="footer_custom_text">Hi, welcome to my blog!</div></div></footer></div><div id="rightside"><div id="rightside-config-hide"><button id="readmode" type="button" title="阅读模式"><i class="fas fa-book-open"></i></button><button id="font-plus" type="button" title="放大字体"><i class="fas fa-plus"></i></button><button id="font-minus" type="button" title="缩小字体"><i class="fas fa-minus"></i></button><button id="translateLink" type="button" title="简繁转换">簡</button><button id="darkmode" type="button" title="浅色和深色模式转换"><i class="fas fa-adjust"></i></button><button id="hide-aside-btn" type="button" title="单栏和双栏切换"><i class="fas fa-arrows-alt-h"></i></button></div><div id="rightside-config-show"><button id="rightside_config" type="button" title="设置"><i class="fas fa-cog fa-spin"></i></button><button class="close" id="mobile-toc-button" type="button" title="目录"><i class="fas fa-list-ul"></i></button><button id="go-up" type="button" title="回到顶部"><i class="fas fa-arrow-up"></i></button></div></div><div id="local-search"><div class="search-dialog"><div class="search-dialog__title" id="local-search-title">本地搜索</div><div id="local-input-panel"><div id="local-search-input"><div class="local-search-box"><input class="local-search-box--input" placeholder="搜索文章" type="text"/></div></div></div><hr/><div id="local-search-results"></div><span class="search-close-button"><i class="fas fa-times"></i></span></div><div id="search-mask"></div></div><div><script src="/hexo3/js/utils.js"></script><script src="/hexo3/js/main.js"></script><script src="/hexo3/js/tw_cn.js"></script><script src="https://cdn.jsdelivr.net/npm/instant.page/instantpage.min.js" type="module"></script><script src="https://cdn.jsdelivr.net/npm/vanilla-lazyload/dist/lazyload.iife.min.js"></script><script src="/hexo3/js/search/local-search.js"></script><script>var preloader = {
  endLoading: () => {
    document.body.style.overflow = 'auto';
    document.getElementById('loading-box').classList.add("loaded")
  },
  initLoading: () => {
    document.body.style.overflow = '';
    document.getElementById('loading-box').classList.remove("loaded")

  }
}
window.addEventListener('load',preloader.endLoading())</script><div class="js-pjax"></div><div class="aplayer no-destroy" data-id="000PeZCQ1i4XVs" data-server="tencent" data-type="artist" data-fixed="true" data-mini="true" data-listFolded="false" data-order="random" data-preload="none" data-autoplay="true" muted></div><script defer="defer" id="fluttering_ribbon" mobile="true" src="https://cdn.jsdelivr.net/npm/butterfly-extsrc@1/dist/canvas-fluttering-ribbon.min.js"></script><script id="canvas_nest" defer="defer" color="0,0,255" opacity="0.7" zIndex="-1" count="99" mobile="true" src="https://cdn.jsdelivr.net/npm/butterfly-extsrc@1/dist/canvas-nest.min.js"></script><script src="https://cdn.jsdelivr.net/npm/butterfly-extsrc@1/dist/activate-power-mode.min.js"></script><script>POWERMODE.colorful = true;
POWERMODE.shake = false;
POWERMODE.mobile = true;
document.body.addEventListener('input', POWERMODE);
</script><script id="click-heart" src="https://cdn.jsdelivr.net/npm/butterfly-extsrc@1/dist/click-heart.min.js" async="async" mobile="true"></script><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/aplayer/dist/APlayer.min.css" media="print" onload="this.media='all'"><script src="https://cdn.jsdelivr.net/npm/aplayer/dist/APlayer.min.js"></script><script src="https://cdn.jsdelivr.net/gh/metowolf/MetingJS@1.2/dist/Meting.min.js"></script><script src="https://cdn.jsdelivr.net/npm/pjax/pjax.min.js"></script><script>let pjaxSelectors = [
  'title',
  '#config-diff',
  '#body-wrap',
  '#rightside-config-hide',
  '#rightside-config-show',
  '.js-pjax'
]

if (false) {
  pjaxSelectors.unshift('meta[property="og:image"]', 'meta[property="og:title"]', 'meta[property="og:url"]')
}

var pjax = new Pjax({
  elements: 'a:not([target="_blank"])',
  selectors: pjaxSelectors,
  cacheBust: false,
  analytics: false,
  scrollRestoration: false
})

document.addEventListener('pjax:send', function () {

  // removeEventListener scroll 
  window.removeEventListener('scroll', window.tocScrollFn)
  window.removeEventListener('scroll', scrollCollect)

  typeof preloader === 'object' && preloader.initLoading()
  
  if (window.aplayers) {
    for (let i = 0; i < window.aplayers.length; i++) {
      if (!window.aplayers[i].options.fixed) {
        window.aplayers[i].destroy()
      }
    }
  }

  typeof typed === 'object' && typed.destroy()

  //reset readmode
  const $bodyClassList = document.body.classList
  $bodyClassList.contains('read-mode') && $bodyClassList.remove('read-mode')

})

document.addEventListener('pjax:complete', function () {
  window.refreshFn()

  document.querySelectorAll('script[data-pjax]').forEach(item => {
    const newScript = document.createElement('script')
    const content = item.text || item.textContent || item.innerHTML || ""
    Array.from(item.attributes).forEach(attr => newScript.setAttribute(attr.name, attr.value))
    newScript.appendChild(document.createTextNode(content))
    item.parentNode.replaceChild(newScript, item)
  })

  GLOBAL_CONFIG.islazyload && window.lazyLoadInstance.update()

  typeof chatBtnFn === 'function' && chatBtnFn()
  typeof panguInit === 'function' && panguInit()

  // google analytics
  typeof gtag === 'function' && gtag('config', '', {'page_path': window.location.pathname});

  // baidu analytics
  typeof _hmt === 'object' && _hmt.push(['_trackPageview',window.location.pathname]);

  typeof loadMeting === 'function' && document.getElementsByClassName('aplayer').length && loadMeting()

  // Analytics
  if (false) {
    MtaH5.pgv()
  }

  // prismjs
  typeof Prism === 'object' && Prism.highlightAll()

  typeof preloader === 'object' && preloader.endLoading()
})

document.addEventListener('pjax:error', (e) => {
  if (e.request.status === 404) {
    pjax.loadUrl('/404.html')
  }
})</script><script async data-pjax src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script></div></body></html>